题目
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例:将如下链表向右移动2位。
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
解决思路
- 第一步:初始时刻定义指针p指向head节点,然后让p指向链表的最后一个节点,并将链表首尾相连构成环。接着让p指向head节点。
- 第二步:将链表向右旋转k-1步,使指向head的指针p走到最终要输出的头节点的上一个节点(注意:设链表的长度为L,向右旋转k步即让指针p从head开始,向右走L-k步)。
- 第三步:将链表从p的下一个节点处断开,p的下一个节点即为要返回的头节点。
代码
- C++代码
# include <stdio.h>
struct ListNode {
int val;
ListNode *next;
ListNode(): val(0), next(nullptr) {}
ListNode(int val): val(val), next(nullptr) {}
ListNode(int val, ListNode *next): val(val), next(next) {}
};
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if (nullptr == head || 0 == k) {
return head;
}
int step = 0; // 记录最终实际要走的步数
int num = 1; // 记录链表节点的个数
ListNode *p = head;
// 遍历链表节点,并将指针p指向链表的尾结点
while (p->next) {
p = p->next;
num += 1;
}
p->next = head; // 将链表构成环,此时p指向尾节点
p = head; // 让p指向头节点
step = k % num; // 若k大于num时,链表需要转整数圈,处理后可以减少移动的步数,不需要转到一整圈
step = num - step - 1; // 先向右旋转k-1步(即指针向右走num-k-1步),让指针p指向最终要输出的头节点的上一个节点
while (step--) {
p = p->next; // 让指针p指向最终要输出的头节点的上一个节点
}
head = p->next; // 指针p的下一个节点即为要输出的头结点
p->next = nullptr; // 从p的下一个节点处断开链表
return head;
}
};
int main() {
ListNode *a = new ListNode(1);
ListNode *b = new ListNode(2);
ListNode *c = new ListNode(3);
ListNode *d = new ListNode(4);
ListNode *e = new ListNode(5);
ListNode *head = a;
a->next = b;
b->next = c;
c->next = d;
d->next = e;
printf("before rotate: ");
while (head) {
printf("%d ", head->val);
head = head->next;
}
printf("\n");
int k = 2;
head = a;
Solution *solution = new Solution();
ListNode *ret = solution->rotateRight(head, k);
printf("after rotate: ");
while (ret) {
printf("%d ", ret->val);
ret = ret->next;
}
return 0;
}
- python代码
# -*- coding: utf-8 -*-
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head or 0 == k:
return head
step = 0 # 记录最终实际要走的步数
num = 1 # 记录链表节点的个数
p = head
# 遍历链表节点,并将指针p指向链表的尾结点
while p.next:
p = p.next
num += 1
p.next = head # 将链表构成环,此时p指向尾节点
p = head # 让p指向头节点
step = k % num # 若k大于num时,链表需要转整数圈,处理后,减少移动的步数,不需要转到一整圈
step = num - step - 1 # 先向右旋转k-1步(即指针向右走num-k-1步),让指针p指向最终要输出的头节点的上一个节点
while step > 0:
p = p.next # 让指针p指向最终要输出的头节点的上一个节点
step -= 1
head = p.next # 指针p的下一个节点即为要输出的头结点
p.next = None # 从p的下一个节点处断开链表
return head
def main():
a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
d = ListNode(4)
e = ListNode(5)
head = a
a.next = b
b.next = c
c.next = d
d.next = e
print("before rotate: ", end='')
while head:
print(head.val, end=' ')
head = head.next
print()
head = a
k: int = 2
solution = Solution()
ret = solution.rotateRight(head, k)
print("after rotate: ", end='')
while ret:
print(ret.val, end=' ')
ret = ret.next
return
if __name__ == "__main__":
main()
说明
- 对应LeetCode第61题。
- 链接:https://leetcode-cn.com/problems/rotate-list/