**题目:**给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例:
解题方法:直觉
链表中的点已经相连,一次旋转操作意味着:
- 先将链表闭合成环
- 找到相应的位置断开这个环,确定新的链表头和链表尾
算法
算法实现很直接: - 找到旧的尾部并将其与链表头相连 old_tail.next = head,整个链表闭合成环,同时计算出链表的长度 n。
- 找到新的尾部,第 (n - k % n - 1) 个节点 ,新的链表头是第 (n - k % n) 个节点。
- 断开环 new_tail.next = None,并返回新的链表头 new_head
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// base cases
if (head == null) return null;
if (head.next == null) return head;
// close the linked list into the ring
ListNode old_tail = head;
int n;
for(n = 1; old_tail.next != null; n++)
old_tail = old_tail.next;
old_tail.next = head;
// find new tail : (n - k % n - 1)th node
// and new head : (n - k % n)th node
ListNode new_tail = head;
for (int i = 0; i < n - k % n - 1; i++)
new_tail = new_tail.next;
ListNode new_head = new_tail.next;
// break the ring
new_tail.next = null;
return new_head;
}
}
复杂度分析
- 时间复杂度:O(N),其中 NN 是链表中的元素个数
- 空间复杂度:O(1),因为只需要常数的空间