旋转链表

旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动 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;
    }
   
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值