61. Rotate List**

61. Rotate List**

https://leetcode.com/problems/rotate-list/

Title Description

Given a linked list, rotate the list to the right by k places, where k is non-negative.

Example 1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL

Example 2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL

C ++ implementation 1

I first introduced the latest thinking of it, then look at the previous practice.

The following code is the idea:

  1. First flip the entire list
  2. Before inverting knode, then flip the num - knodes
  3. Splicing two sub-lists

As the general idea, but there are some details to consider, in turn introduce the following:

  1. First, kthere may be very large, if we know the number of nodes of the list num, we only need to deal with k %= numthe situation. In order to count the number of nodes linked list, this is done at the flip of this list, so reverseincreasing the function int &numof this parameter.
  2. We only need to consider k %= numthe situation, and if at this time k == 0, then return directly to the original list, but the list in the first step has been flipped, so pay attention to flip back.
  3. After entering the first two steps, originally intended to overturn ago knodes, then flipped back of num - knodes, but will find that there is a problem that is not effectively splicing two lists, if you want to splice two lists, you need to find the last before a child node of the list, of course, also possible to do so, but do not feel very elegant.
  4. Thus, another way is to first flip the back of num - knodes after completion of rollover effect is as follows:
  1. After the third step, you need to flip 5->4, and let the 5point 1. In fact, this idea and reversefunction of the logic is the same.
    But there is a need to pay attention to detail, headmost move to 4, equivalent to 3a head end, we need to use end = p->nextfirst 3saved to endthe , but it can not be whileused directly in the cycle head != p->next; it is because the node 4last change, the corresponding p will change, leading to the final p->nextthey no longer point 3 below with a brief description of FIG step:
class Solution {
private:
    ListNode* reverse(ListNode *head, int &num) {
        ListNode *prev = nullptr;
        while (head) {
            auto tmp = head->next;
            head->next = prev;
            prev = head;
            head = tmp;
            num += 1;
        }
        return prev;
    }
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (!head || !head->next) return head;
        int num = 0;
      	// 第一步
        head = reverse(head, num);
        k = k % num;
        if (k == 0) return reverse(head, num);
        auto p = head;
        while (--k) p = p->next;
        // 第二步
        auto rlist = p->next;
        rlist = reverse(rlist, num);
        // 第三步
        auto end = p->next;
        while (head != end) {
            auto tmp = head->next;
            head->next = rlist;
            rlist = head;
            head = tmp;
        }
        return rlist;
    }
};

2 in C ++

Two years ago, the code:

Idea: use recursion can be very simple solution This question, if you want to list the rotation k times, it can be rotated in k - 1 on the basis of the list of the last node at the head of the list, so get the k-times list. but there optimization is important to note, otherwise it will report a timeout, after all, may be large k, we observe that, if k is divisible by the number of nodes in the list, then the list will be rotated original list itself.

class Solution {
private:
    ListNode* rotateRight(ListNode *head, int n, int k) {
      	// 如果 k 能整除 n, 那么直接返回链表本身
        if ((k % n) == 0) return head;
		
      	// 否则只要在第 k-1 次旋转得到的链表的基础上, 做一些简单的操作即可.
      	// 注意 while 循环中判断 ptr->next->next 是否存在, 这样是为了让
      	// ptr 最终的值是倒数第二个节点.
        head = rotateRight(head, n, k - 1);
        auto ptr = head;
        while (ptr->next && ptr->next->next)
            ptr = ptr->next;
        auto tmp = ptr->next;
        ptr->next = nullptr;
        tmp->next = head;
        head = tmp;
        return head;

    }
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (!head || !head->next) return head;
      	// 用 n 统计链表中节点的个数
        int n = 0;
        auto ptr = head;
        while (ptr) {
            ptr = ptr->next;
            ++ n;
        }
        return rotateRight(head, n, k);
    }
};

C ++ implementation 3

From LeetCode Forum:

My clean C++ code, quite standard (find tail and reconnect the list)

Idea of this approach is to first determine the size of the list and find the last tail node, then inflicted cyclic chain tail->next = head. According After k %= lendetermining where disconnection list. (If not using an if statement k %= len, the for loop the determination condition i < len - kis actually i < len - k % len.

Corresponds to the first ring, then left off. tailTo move len - kstep intuitive to think that, if the pointer can be moved backward, the backward movement kstep is most convenient; if you can not move backward, then we can move forward len - kstep.

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(!head) return head;
        
        int len=1; // number of nodes
        ListNode *newH, *tail;
        newH=tail=head;
        
        while(tail->next)  // get the number of nodes in the list
        {
            tail = tail->next;
            len++;
        }
        tail->next = head; // circle the link

        if(k %= len) 
        {
            for(auto i=0; i<len-k; i++) tail = tail->next; // the tail node is the (len-k)-th node (1st node is head)
        }
        newH = tail->next; 
        tail->next = NULL;
        return newH;
    }
};
Published 455 original articles · won praise 8 · views 20000 +

Guess you like

Origin blog.csdn.net/Eric_1993/article/details/105004378