leetcode92. Reverse Linked List II

来源:互联网 发布:台湾ptt评论知乎文章 编辑:程序博客网 时间:2024/06/09 18:39

某位大牛写的算法,简直五体投体,里面灵活地运用了简单逆序链表的思想,为啥我就想不到呢,真的比较笨,要多体会

【解析】

consider m,n as the cutting point ,and cut the linklist to three parts. The first  and third part is just  marked as the same of  original link list,and the second part should be reversed and we should notice to save the node in m to let it connect with the third part.

public ListNode reverseBetween(ListNode head, int m, int n) {ListNode dummyhead = new ListNode(0);dummyhead.next = head;ListNode sublisthead = new ListNode(0);ListNode sublisttail = new ListNode(0);int count = 1;ListNode pre_cur = dummyhead, cur = head;while(count <=n){ListNode temp = cur.next;if (count < m)pre_cur = cur;else if (count == m){sublisttail = cur;sublisthead.next = cur;}else if (count > m){cur.next = sublisthead.next;sublisthead.next = cur;}cur = temp;++count;}pre_cur.next = sublisthead.next;sublisttail.next = cur;return dummyhead.next;}

做这个算法深刻理解了对象引用的问题,

对于listNode里面的next操作,改变的是内部的值,会有链式反应。(内部值发生改变)

对于listNode对应的整个变量操作,则不会产生链式反应。(引用发生改变)

例如:cur.next会改变head;但是cur不会改变head


对以上算法进行了修改,便于理解

public class Solution {   public ListNode reverseBetween(ListNode head, int m, int n) {ListNode dummyhead = new ListNode(0);dummyhead.next = head;ListNode sublisthead = new ListNode(0);ListNode sublisttail = new ListNode(0);int count = 1;ListNode pre_cur = dummyhead, cur = head;while(count <=n){ListNode temp = cur.next;if (count < m)pre_cur = cur;else if (count == m){sublisttail = cur;sublisthead.next = sublisttail;//连接sublisttail}else if (count > m){cur.next = sublisthead.next;sublisthead.next = cur;}cur = temp;++count;}pre_cur.next = sublisthead.next;sublisttail.next = cur;return dummyhead.next;}


 public ListNode reverseBetween(ListNode head, int m, int n) {           ListNode dummyhead = new ListNode(0);        dummyhead.next = head;        ListNode sublisthead =new ListNode(0);        ListNode sublisttail =new ListNode(0);        int count = 1;        ListNode pre_cur = dummyhead, cur = head;        while(count <=n){            ListNode temp = cur.next;            if (count < m)                pre_cur = cur;            else if (count == m){                sublisttail = cur;//                sublisthead = cur;            }else if (count > m){                cur.next = sublisthead.next;                sublisthead.next = cur;            }            cur = temp;            ++count;        }       ListNode p=sublisthead;        while(p.next!=null){            p=p.next;        }        p.next=sublisttail;//连接sublisttail        sublisttail.next = cur;        pre_cur.next = sublisthead.next;        return dummyhead.next;    }


总结:

上述是in-place algorithm 需要四个标志:1、本身链表  2、链表的游标 3、临时链表:保存游标之后的结点  4、翻转链表:返回用,保存游标之前的结点

还有一种是重新生成一个链表的相关算法,也需要三个标志:1、本身链表:返回用 2、链表的游标  3、新建结点:创建新的结点用.

如:两数相加算法

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {       ListNode result=new ListNode(0);  //1       ListNode p1=l1,p2=l2;       ListNode r=result;                //2       int mode=0;       while(p1!=null||p2!=null||mode!=0){           ListNode temp=new ListNode(0);//3           int val=((p1==null)?0:p1.val)+((p2==null)?0:p2.val)+mode;           temp.val=val%10;           mode=val/10;           r.next=temp;           r=r.next;           p1=(p1==null)?p1:p1.next;           p2=(p2==null)?p2:p2.next;       }    //   if(mode!=0){    //       r.next=new ListNode(mode);    //   }       return result.next;    }




原创粉丝点击