力扣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;

    }
};

你可能感兴趣的:(#,力扣-C++,链表,leetcode,c++,数据结构,算法)