右旋单链表 Rotate List

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

For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.

思路:对于数组来说,右旋的方法是两轮逆转。对于链表,结点的位置是逻辑相连的,右旋时只需要拆开两截在另一头接上,不需要移动链的内部,更不需要交换结点的元素。所以操作的关键是根据数字k,找到链表拆解的位置。注意k可以超过链表元素的个数,即右旋几圈跟没右旋一样。

代码一:

class Solution {
public:
    ListNode *rotateRight(ListNode *head, int k) {
        if(head == NULL)
            return NULL;
        ListNode *p1, *p2;
        p1 = p2 = head;
        
        while(k > 0)
        {
            k--;
            p1 = p1->next;
            if(p1 == NULL)//循环跑圈,把k跑到0
                p1 = head;
        }
        while(p1->next != NULL)
        {
            p1 = p1->next;
            p2 = p2->next;
        }//此时:p1指向链表尾结点,p2指向链表右旋位置
        
        p1->next = head;
        head = p2->next;
        p2->next = NULL;
        return head;
    }
};

代码二:也可以先求出链表长度,然后通过取模运算来计算旋转位置。当k很大的时候可以避免代码一循环跑圈。

class Solution {
public:
    ListNode *rotateRight(ListNode *head, int k) {
        if(head == NULL || k == 0)
            return head;
        ListNode *p1, *p2;
        p1 = p2 = head;
        
        int n = 1;
        while(p1->next != NULL) //计算链表长度并记录尾结点
        {
            n++;
            p1 = p1->next;
        }
        
        k = n - k%n;
        for(int i=1;i<k;i++) //找到新表尾
            p2 = p2->next;
        
        p1->next = head;
        head = p2->next;
        p2->next = NULL;
        return head;
    }
};

你可能感兴趣的:(右旋单链表 Rotate List)