题目描述
给你一个链表的头节点 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]
提示:
- 链表中节点的数目在范围 [0, 500] 内
- -100 <= Node.val <= 100
- 0 <= k <= 2 * 109
解题方法
遍历
链表向右移动k
个位置,实际上就是将新链表以倒数第k
个节点为新的头结点,若倒数第k+1
个节点存在,则以倒数第k+1
个节点为新链表的尾节点。
这样思路一下就开阔了,我们只需要通过遍历找到倒数第k
个节点、倒数第k+1
个节点和旧链表的尾节点,然后将新链表的指针重新指向新的节点。
java代码
ListNode结构
public class ListNode {
public int val;
public ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
旋转链表方法
public ListNode rotateRight(ListNode head, int k) {
if (head == null || k == 0) {
return head;
}
ListNode node = head;
// 记录尾节点
ListNode tail = null;
// 记录链表长度
int length = 0;
while(node != null) {
length++;
tail = node;
node = node.next;
}
// 当k > length时,对k取余
k = k % length;
if (k == 0) {
return head;
}
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
// 快指针
ListNode fast = dummyNode;
for(int i = 0; i < k; i++) {
fast = fast.next;
}
// 利用快慢指针将node指针指向倒数第k个节点
node = dummyNode;
// pre指针指向node的前一个节点
ListNode pre = null;
while(fast != null) {
fast = fast.next;
pre = node;
node = node.next;
}
// 旧链表的尾节点的next指针指向head
tail.next = head;
// pre变为了新链表的尾节点,pre节点的next指针指向null
pre.next = null;
return node;
}
复杂度分析
时间复杂度:
O
(
N
)
O(N)
O(N),需要遍历两次链表。
空间复杂度:
O
(
1
)
O(1)
O(1),只有常数级别的变量存储。
相似题目
[leetcode] 19. 删除链表的倒数第 N 个结点
[leetcode] 25. K 个一组翻转链表
- 个人公众号
- 个人小游戏