力扣 - 61. 旋转链表
题目
思路1
- 可以将链表首位相连接,变成一个循环链表
- 再通过
len - k % len可得出需要将指向head的引用往后移动多少,将head前一个(即新的链表的尾部)的next指向null,最后返回head即可
代码
class Solution {
public ListNode rotateRight(ListNode head, int k) {
//如果出现链表为空、链表的元素只有一个、k为0,那么就直接返回head
if (head == null) {
return null;
}
if (head.next == null || k == 0) {
return head;
}
//计算链表的长度
ListNode oldHead = head;
ListNode newHead = null;
int len = 1;
while (oldHead.next != null) {
oldHead = oldHead.next;
len++;
}
oldHead.next = head;
//减1是为了只获取到新的头结点前一个结点
k = len - k % len + 1;
while (k > 0) {
head = head.next;
k--;
}
newHead = head.next;
head.next = null;
return newHead;
}
}
复杂的分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)
思路2
- 利用双指针,先求出总的链表长度len,再在不超过链表的长度的移动距离
k = k % len,然后让fast指针后移k个位置,然后将快慢指针同时后移,直到fast指针到达最后一个结点停止移动。然后用newHead引用记录low.next这个结点(就是我们新链表的头结点),将fast.next指向head,low.next指向null,最后返回newHead即可
代码
class Solution {
public ListNode rotateRight(ListNode head, int k) {
//如果出现链表为空、链表的元素只有一个、k为0,那么就直接返回head
if (head == null) {
return null;
}
if (head.next == null || k == 0) {
return head;
}
//先定义快、慢指针
ListNode low = head;
ListNode fast = head;
//临时的指针
ListNode tmp = head;
//计算链表的总长度
int len = 1;
while (tmp.next != null) {
tmp = tmp.next;
len++;
}
//移动的距离不超过链表的长度
k = k % len;
//移动fast指针k长度
for (int i = 0; i < k; i++) {
fast = fast.next;
}
//双指针同时移动
while (fast.next != null) {
low = low.next;
fast = fast.next;
}
fast.next = head;
ListNode newHead = low.next;
low.next = null;
return newHead;
}
}
复杂的分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)
我走得很慢,但我从不后退!

浙公网安备 33010602011771号