[LeetCode]91. 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.

Subscribe to see which companies asked this question

 
解法1:与题目Rotate Array旋转数组相似,借鉴其中的三次旋转法,分别使用Reverse Linked ListReverse Linked List II即可解决。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        ListNode* curr = head;
        int length = 0;
        while (curr != NULL) {
            ++length;
            curr = curr->next;
        }
        if(length > 0) k %= length;
        if(length == 0 || length == 1 || k == 0) return head;
        head = reverseList(head);
        if(k > 1) head = reverseBetween(head, 1, k);
        if(k + 1 < length) head = reverseBetween(head, k + 1, length);
        return head;
    }
private:
    ListNode* reverseList(ListNode* head) {
        ListNode* rHead = NULL;
        ListNode* curr = head;
        ListNode* pTail = NULL;
        while (curr != NULL) {
            ListNode* pNext = curr->next;
            if (pNext == NULL)
                rHead = curr;
            curr->next = pTail;
            pTail = curr;
            curr = pNext;
        }
        return rHead;
    }
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        if (head == NULL || head->next == NULL || m == n) return head;
        ListNode* help = new ListNode(0);
        help->next = head;
        ListNode* prev = help;
        for (int i = 0; i < m - 1; ++i)
            prev = prev->next;
        ListNode *curr = prev->next, *next = curr->next, *temp = curr, *last = NULL;
        for (int i = m; i < n; ++i) {
            last = next->next;
            next->next = curr;
            curr = next;
            next = last;
        }
        prev->next = curr;
        temp->next = last;
        return help->next;
    }
};

解法2:因为在k处旋转链表只需要断开第n-k个节点和第n-k+1个节点(n为链表长度)然后新链表的头设为第n-k+1个节点,第n-k个节点的next指针设为NULL即可,因此可以先扫描一次链表统计节点个数,然后再从头开始前移n-k-1步,处理好这个节点的next指针即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        ListNode* curr = head;
        int length = 0;
        while (curr != NULL) {
            ++length;
            curr = curr->next;
        }
        if(length > 0) k %= length;
        if (length == 0 || length == 1 || k == 0) return head;
        curr = head;
        for (int i = 0; i < length - k - 1; ++i)
            curr = curr->next;
        ListNode* newHead = curr->next; // 旋转后新的头节点
        curr->next = NULL; // 断开链表
        curr = newHead;
        while (curr->next != NULL)
            curr = curr->next;
        curr->next = head; // 原链表的尾节点和头节点链接起来
        return newHead;
    }
};
原文地址:https://www.cnblogs.com/aprilcheny/p/4972501.html