旋转链表

    科技2026-02-11  18

    旋转链表

    给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。 示例 1: 输入: 1->2->3->4->5->NULL, k = 2 输出: 4->5->1->2->3->NULL 解释: 向右旋转 1 步: 5->1->2->3->4->NULL 向右旋转 2 步: 4->5->1->2->3->NULL

    解答:使用双指针法 首先定义指针pos和int型变量size,遍历完之后pos指向链表的最后一个元素(NULL前面的那个元素),size即为链表的长度。 我们发现,假如k刚好是size的整数倍的话,其实链表旋转了k次之后,压根就没有变化(直接返回head即可),所以不管k是多少,链表旋转k次的结果,会和旋转k % size次相同。 定义一个cut指针指向head,当cut往后走size-move-1个单位之后,它后面的部分就是要断开的部分。 比如说,链表是a->b->c->d->e->f->g,k=3。那么会有:size=7、pos最终指向g、move=3和size-move-1=3。 最终链表应该是e->f->g->a->b->c->d,所以e->f->g是应该被断开的部分,然后接到a的前面。 于是乎,cut从head处往后走size-move-1个单位之后,会来到d,然后cut后面刚好就会是e->f->g。 让cut -> next = nullptr,就会把e->f->g从链表中断开。 这时候我们要做的只剩下把e->f->g接上a就大功告成了。在代码中,result就指向e,是需要最终链表的头节点,而一开始的pos大家别忘了,它指向g,就是初始链表的尾节点。 所以只需要写pos -> next = head,然后return result就可以了。

    class Solution { public: ListNode* rotateRight(ListNode* head, int k) { if(!head||!head->next||k==0) return head; ListNode* pos = head; int size = 1, move = 0; while(pos&&pos->next){ pos = pos->next; size++; } move = k%size; if(move==0) return head; ListNode* cut = head; for(int i=0;i<size-move-1;++i){ cut = cut->next; } ListNode* result = cut->next; pos->next = head; cut->next = nullptr; return result; } };
    Processed: 0.011, SQL: 9