思路不难,就是将链尾拆下来插到链首 k 次,类似于 “循环右移”。需要注意的是如果直接写循环 k 次会超时(题目中 k 的范围是 0 <= k <= 2 * 109),这个时候的优化思路是统计一下链表的元素总数 count,再把循环次数设为 k 模 count,就能应对 k 很大但 count 很小的情况了(避免了大量重复的右移)。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* rotateRight(ListNode* head, int k) { pHead = new ListNode(0, head); tail = pHead; if(head == NULL || head->next == NULL || k == 0) return head; int count = 0; for(ListNode* q = pHead; q->next != NULL; count++, q = q->next) { if(q->next->next == NULL) tail = q; //统计count的时候顺便把tail的位置也确定下来 } for(int i = 0; i < k % count; i++) { //循环k mod count次 deleteAndPutHead(); refreshTail(); } return pHead->next; } private: ListNode* pHead = NULL; ListNode* tail = NULL; void deleteAndPutHead() { auto p = tail->next; tail->next = NULL; p->next = pHead->next; pHead->next = p; } void refreshTail() { tail = pHead; while(tail->next->next != NULL) { tail = tail->next; } } };