题目地址:旋转链表
起初想到的思路是不断将最后的节点用头插法插入链表,直到插入k次
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head == null || k==0)
return head;
ListNode tmp = head;
int len = 0;
//求链表长度
while(tmp != null){
tmp = tmp.next;
len++;
}
k %= len; //以防k大于链表长度,以len为周期
if(k == 0)
return head;
ListNode chs = head; //保存头节点
tmp = head;
//先将tmp向右移动k个位置
while(k > 0){
tmp = tmp.next;
k--;
}
//两个快慢指针,当tmp到达空指针处,head距离末尾正好k个距离
while(tmp.next != null){
head = head.next;
tmp = tmp.next;
}
//res为新的头节点
ListNode res = head.next;
//断开连接,生成尾节点
head.next = null;
//后半段尾节点指向前半段头节点
tmp.next = chs;
return res;
}
}
结果:
官方采用了一种思路,先将首尾闭合,想不到:
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// 头节点为空返回空,只有一个节点返回头节点
if (head == null) return null;
if (head.next == null) return head;
// 首尾闭合,同时n记录了链表长度
ListNode old_tail = head;
int n;
for(n = 1; old_tail.next != null; n++)
old_tail = old_tail.next;
old_tail.next = head;
// 求新的尾节点和新的头节点
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;
// 将环打开
new_tail.next = null;
//返回新的头节点
return new_head;
}
}
结果: