力扣61-旋转链表-C++双指针法

一、运行结果

 

二、题目

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
示例 2:
输入:head = [0,1,2], k = 4
输出:[2,0,1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-list

三、思路

注意,移动的次数k有可能大于链表长度len,但移动 len 次和没有移动是一样的,所以这里先获取链表长度len(遍历一遍链表),然后将 k 对 len 取余,确保 k 小于len,设置两个指针pre 和p,p开始指向头结点,pre指向其前驱结点,将p往后移动 k-1 个位置(k 已经取余),此时pre 和 p之间间隔k个结点,然后pre 和 p 同步向后移动, 直至p 指向最后一个节点,将pre->next 到p间的这段链表整段插入到新建的头结点dummy和head之间即得到结果。

四、代码

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head == NULL || k == 0) return head;
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* pre = dummy;
        ListNode* p = head;
        int len =0;
        while(p){  //获取链表长度
            len++;
            p = p->next;
        }
        if(k >= len) {  
            k = k % len;      //确保k小于len,多移len次变回原样
            if(k == 0) return head;
        }
        p = head;
        for(int i=0; i < k-1; i++){  //退出时pre, p之间相隔k个节点
            p = p->next; 
        }    
        while(p != NULL && p->next != NULL){
            p= p->next;         //退出循环 p 指向最后一个节点
            pre = pre->next;
        }
        p->next = dummy->next;  //将pre->next到p的这段整段插入到dummy和head之间
        dummy->next = pre->next;
        pre->next = NULL;
        return dummy->next;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值