一、运行结果
二、题目
给你一个链表的头节点 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;
}
};