原题
解法
由于k 的长度是可能大于链表长度的,所以需要进行取模,减少重复移动
快慢指针
这种选择链表比较适合使用快慢指针的方法进行处理:
- 获取链表长度
- 对k进行取模
- 定义快慢指针,快指针先移动k位置,然后快慢同时移动,知道快指针到最后一个节点
- 将快指针next指向head
- head定义为慢指针的next
- 慢指针next指针指向null
代码
public ListNode rotateRight(ListNode head, int k) {
if (null == head) {
return head;
}
int c = 0;
ListNode fast = head;
while (null != fast && ++c > 0) {
fast = fast.next;
}
k %= c;
fast = head;
ListNode slow = head;
for (int i = 0; i < k; i++) {
fast = fast.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
fast.next = head;
head = slow.next;
slow.next = null;
return head;
}
成环后处理
- 遍历得到链表长度后,对k取模,尾节点的next指向head,形成环
- 算出head到新head的距离
- 遍历,然后将该节点next执行null,返回新head
代码:
public ListNode rotateRight2(ListNode head, int k) {
if (null == head) {
return head;
}
//遍历找到最后一个,并计算长度
int c = 0;
ListNode tmp = head;
while (null != tmp.next && ++c > 0) {
tmp = tmp.next;
}
c++;
tmp.next = head;
k %= c;
k = c - k;
for (int i = 0; i < k - 1; i++) {
head = head.next;
}
tmp = head.next;
head.next = null;
return tmp;
}
参考: 三叶的刷题笔记