1 class Solution { 2 public ListNode rotateRight(ListNode head, int k) { 3 ListNode p1 = head; 4 if (p1 == null) 5 return head; 6 7 //计算链表长度 8 int cnt = 0; 9 while (p1 != null) { 10 cnt++; 11 p1 = p1.next; 12 } 13 14 //预处理k并获得新的头结点 15 k = cnt - (k % cnt); 16 p1 = head; 17 for (int i = 0; i < k; i++) { 18 if (p1.next == null) { 19 p1 = head; 20 continue; 21 } 22 p1 = p1.next; 23 } 24 ListNode newHead = p1; 25 26 //从新头节点开始遍历 27 ListNode p2 = newHead; 28 while (p2 != null && p2.next != newHead) { 29 if (p2.next == null) { 30 p2.next = head; 31 continue; 32 } 33 p2 = p2.next; 34 } 35 p2.next = null; 36 return newHead; 37 } 38 }
思路:
1. 预处理k。因为如果k比较大,可能会超时。k %= cnt;
2. 找到新的头节点。从原头节点倒着往回退k次就行了,但是这里链表是单向的。变换一下思路,即从原头节点向前n - k次即可。
3.从新头节点开始遍历,到新头节点的前一个节点(即新尾节点)为止,中间遇到原尾节点时要变向指向原头节点,最后新尾节点指向null终止。
其他思路
这题推荐是用two pointers来做,暂时还没研究。不过原理应该都是类似的吧。
注意事项:
链表的题目实现比思路更容易出错。
稍微总结了几个方面:
1. 对每个node操作前,要判断是否为null,避免出现null.next的问题。
2. 如果要修改一个node的指向,一定要先保留原来指向的next node。否则修改指向后,就找不到下一个节点了。
3. (针对这题)30行修改了p2的next指向,则p2在当次迭代中不应该再后移,因为判断条件中存在 p2.next != newHead 的条件。