leetcode 61 链表旋转

 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 的条件。

猜你喜欢

转载自www.cnblogs.com/hiyashinsu/p/10682899.html