题目
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
解释:5,1,2,3,4->4,5,1,2,3
输入:head = [0,1,2], k = 4
输出:[2,0,1]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr || k == 0) return head;
int len = 1;//记录链表长度
ListNode *p = head;//指向链表头,用改指针遍历链表
while(p->next){
len++;
p = p->next;
}
k =len- k % len;//更新k的值,从原链表的末节点开始,右移k位到新链表的末节点
p->next = head;//首尾相连,成环
for(int i = 0; i<k; i++){
p = p->next;
}
head = p->next;//新链表的首节点
p->next = nullptr;//将环断开
return head;
}
};
- 时间复杂度O(n)
- 空间复杂度O(1)
- 思路
- 如果链表为空或k为0,直接返回首节点
- 遍历链表,求它的长度。k或许会大于链表长度,先对长度取余,求到k的新值。要求将每个节点右移k位后的链表,考虑如何找到右移k位后成为最后一个节点的节点,即将链表首尾相连成环,从移动前链表的最后一个节点开始右移n-k位,此时p指向的节点就是新的节点的末节点。
- 将head指向该节点的后继,然后将环断开,返回head