92 Reverse Linked List II
来源:互联网 发布:云计算与虚拟化的区别 编辑:程序博客网 时间:2024/06/05 17:03
逆转部分LinkList,和逆转整个LinkList的题目是一样的,沿用之前的思路就可以,新建一个dummyNode,把要逆转的部分通过头插法连接起来。
这道题稍微有点麻烦,就是分步骤:
1,找到逆转部分的之前一个node,作为第一个attach point
2,确定逆转部分的最后一个node,作为第二个attach point
3,完成扭转之后,attach两次既可!
一个技巧,因为m可以等于1,那么逆转部分的前一个node怎么确定呢?那就通过新建一个dummyHead,连在head之前,这样就非常方便了,很多情况下,通过dummyHead可以是问题简化很多。代码如下
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { if(head==null || head.next==null) return head; ListNode dummyHead= new ListNode(0); dummyHead.next=head; ListNode curr=dummyHead; int jump=0; while(jump<m-1){ curr=curr.next; jump++; } // after while loop, jump=m-2 and curr points to the node before m-th node ListNode frontAttach=curr; // set the anchor // advance 1 node curr=curr.next; jump++; // use the same idea of reverse the whole list ListNode dummy= new ListNode(0); ListNode backAttach=curr; while(jump<=n){ ListNode target=curr; curr=curr.next; target.next=dummy.next; dummy.next=target; jump++; } // do 2 attach, for the reversed segment frontAttach.next=dummy.next; backAttach.next=curr; return dummyHead.next; // Do NOT return head, it is wrong, when m==1 } }
参考了别人的解法,有一个while循环就完成逆转的,代码是比较简洁,但是while内部的多次node 移动不是非常intuitive,需要画图才看得清楚,可能在熟悉之后还是可以使用的,如果头脑里没有这个画面,还是不要轻易使用, 容易出错。代码如下
public ListNode reverseBetween(ListNode head, int m, int n) { if(head == null) return null; ListNode dummy = new ListNode(0); // create a dummy node to mark the head of this list dummy.next = head; ListNode pre = dummy; // make a pointer pre as a marker for the node before reversing for(int i = 0; i<m-1; i++) pre = pre.next; ListNode start = pre.next; // a pointer to the beginning of a sub-list that will be reversed ListNode then = start.next; // a pointer to a node that will be reversed for(int i=0; i<n-m; i++) { start.next = then.next; then.next = pre.next; pre.next = then; // 以上三句就是每次把then node移动到pre后面,这样就完成了逆转,pre和start之间的node顺序已经稳定,所以不需要做改变 then = start.next; // 始终保持then在start后面 } return dummy.next; }
结合我代码的思路,这上面的代码其实还比较好理解,
第一个for loop,通过移动m-1次,把光标指针移到m-1个node处,然后初始化start,和始终在start后面的end
第二个for loop,本质就是挪动n-m次node,所以有i=0; i<n-m,每次挪动需要换图来理解,至少画2个循环才看得清楚,第一次的pre.next 和第二次的pre.next的区别就让你看得清楚了。有了理解和画面感,还是比较容易记忆的。
0 0
- 92Reverse Linked List II
- 92Reverse Linked List II
- 92 Reverse Linked List II
- 92-reverse linked list II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- Reverse Linked List II
- hdu 1480 钥匙计数之二
- linux 达人养成计划 II笔记
- java日志文件log4j.properties配置详解
- CSShack 布局
- 编译 OpenCV 避免下载 linux-64-opencv-2.4.11-nppy27_0.tar.bz2
- 92 Reverse Linked List II
- Sort a linked list using insertion sort
- 点击启动,暂停动画
- git push -u origin master 出错 \Permission denied (publickey). fatal: Could not read from remote repo
- Java多线程——Callable、Future和FutureTask
- ViewHolder报空指针????
- 初试 sproto
- ERROR in AppModule is not an NgModule
- 448. Find All Numbers Disappeared in an Array