zoukankan      html  css  js  c++  java
  • LeetCode: Tags-[Linked List]

    LeetCode: Tags-[Linked List]

    2. Add Two Numbers: https://leetcode.com/problems/add-two-numbers/

    两个单链表代表倒序的数字, 求和: (Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8)

    解法1:(sum初始为0, 用sum依次记录l1和l2的值, sum%10即为该node对应的数; 求下一个节点, sum初始为sum/10, 即保存了进位;  对于最后一位节点单独处理是否有进位; ps: 定义dummy作为返回链表的表头, 是静态的; head是动态的, 从dummy开始向后移动(第一个使用的是head.next))

    (1.dummy,head,sum;  2.while(),sum,if()-sum-next, if()-sum-next;  3.h.next=new(sum%10),h=h.next;  4.if()h.next=new(1),return dummy.next;)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    11         if (l1 == null && l2 == null) return null;
    12         ListNode dummy = new ListNode(0);
    13         ListNode head = dummy;
    14         int sum = 0;
    15         while (l1 != null || l2 != null) {
    16             sum /= 10;
    17             if (l1 != null) {
    18                 sum += l1.val;
    19                 l1 = l1.next;
    20             }
    21             if (l2 != null) {
    22                 sum += l2.val;
    23                 l2 = l2.next;
    24             }
    25             head.next = new ListNode(sum % 10);
    26             head = head.next;
    27         }
    28         if (sum / 10 == 1) head.next = new ListNode(1);
    29         return dummy.next;
    30     }
    31 }
    View Code

    19. Remove Nth Node From End of List:https://leetcode.com/problems/remove-nth-node-from-end-of-list/

    删除倒数第N个节点: (滑动窗口。左右指针,右指针移n,判断right.next;)

    我的解法:<Two Pointer><Sliding Window>(定义左右指针,初始指向dummy; for循环right移动n次, 此时right和left间隔即为n; 判断right.next!=null, 则窗口移动; 最后删除tar节点即: left.next=left.next.next; 示例:dummy-1-2-3-4-5,n=2;  for循环两次, right-2,left-dummy; while,right-5,left-3; right.next=null,停止while循环; 删除left.next; 返回dummy.next)

    <1.dummy,next,left,right;  2.for(n)right;  3.while(.next!=)left right;  4.l.n=l.n.n,return dummy.next;>

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode removeNthFromEnd(ListNode head, int n) {
    11         ListNode dummy =  new ListNode(0);
    12         dummy.next = head;
    13         ListNode left = dummy;
    14         ListNode right = dummy;
    15         for (int i = 0; i < n; i++) {
    16             right = right.next;
    17         }
    18         while (right.next != null) {
    19             left = left.next;
    20             right = right.next;
    21         }
    22         left.next = left.next.next;
    23         return dummy.next;
    24     }
    25 }
    View Code

    21. Merge Two Sorted Lists: https://leetcode.com/problems/merge-two-sorted-lists/

    合并两个有序链表:

    (解法1:迭代;定义dummy,定义head=dummy;while(两个都不为null),判断l1和l2的值,小的作为head.next并移动,移动head指针; 最后if判断不为null的作为next;

    解法2:递归;有null则return;否则比较大小,小的数l.next=递归,return;)

    我的解法:

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    11         ListNode dummy1 = new ListNode(0);
    12         dummy1.next = l1;
    13         l1 = dummy1;
    14         ListNode dummy2 = new ListNode(0);
    15         dummy2.next = l2;
    16         l2 = dummy2;
    17         ListNode dummy = new ListNode(0);
    18         ListNode head = dummy;
    19         while (l1.next != null && l2.next != null) {
    20             if (l1.next.val <= l2.next.val) {
    21                 ListNode tmp = new ListNode(l1.next.val);
    22                 head.next = tmp;
    23                 head = head.next;
    24                 l1 = l1.next;
    25             } else {
    26                 ListNode tmp = new ListNode(l2.next.val);
    27                 head.next = tmp;
    28                 head = head.next;
    29                 l2 = l2.next;
    30             }
    31         }
    32         if (l1.next == null) {
    33             while (l2.next != null) {
    34                 ListNode tmp = new ListNode(l2.next.val);
    35                 head.next = tmp;
    36                 head = head.next;
    37                 l2 = l2.next;
    38             }
    39         }
    40         if (l2.next == null) {
    41             while (l1.next != null) {
    42                 ListNode tmp = new ListNode(l1.next.val);
    43                 head.next = tmp;
    44                 head = head.next;
    45                 l1 = l1.next;
    46             }
    47         }
    48         return dummy.next;
    49     }
    50 }
    View Code

     改进:(当l1与l2都不为null时,比较l1和l2的val; 加入小的val; 最后将长的list添加到head的结尾)(ps: .next or not总是很乱,写前思考清楚,画出示例, 标上指针)

    (1.dummy,head;  2.while(&&) if(),.next=l1,l1=l1.n; else().next=l2,l2=l2.n;  3.head=head.n;  4.if().next=l; if();  5.return dummy.next)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    11         ListNode dummy = new ListNode(0);
    12         ListNode head = dummy;
    13         while (l1 != null && l2 != null) {
    14             if (l1.val <= l2.val) {
    15                 head.next = l1;
    16                 l1 = l1.next;
    17             } else {
    18                 head.next = l2;
    19                 l2 = l2.next;
    20             } 
    21             head = head.next;
    22         }
    23         if (l1 != null) head.next = l1;
    24         if (l2 != null) head.next = l2;
    25         return dummy.next;
    26     }
    27 }
    View Code

    解法2:递归Recursion

     1 public ListNode mergeTwoLists(ListNode l1, ListNode l2){
     2         if(l1 == null) return l2;
     3         if(l2 == null) return l1;
     4         if(l1.val < l2.val){
     5             l1.next = mergeTwoLists(l1.next, l2);
     6             return l1;
     7         } else{
     8             l2.next = mergeTwoLists(l1, l2.next);
     9             return l2;
    10         }
    11 }
    View Code

    24. Swap Nodes in Pairs: https://leetcode.com/problems/swap-nodes-in-pairs/

    两两交换相邻节点:

    (解法1:迭代;dummy,head;while(head后两节点都不为null),首先保存n1,n2;然后三步:head.next=n2, n1.next=n2.next, n2.next=n1; 最后head移动到n1;

    解法2:递归;判null;首先保存head.next为n;两步:head.next=递归(head.next.next),n.next=head; 返回n;)

    解法1:<Recursion>(O(n)space,与题目要求constant space不符1.判空,head=null或者head.next=null都不需要继续了; 2.tmp保存head.next;  3.head.next->下一对head,即swap;  4.tmp->head;  5.return tmp)

    (1.if(||);  2.tmp;  3.head.next;  4.tmp.next;  5.return tmp;)

     1 public class Solution {
     2     public ListNode swapPairs(ListNode head) {
     3         if ((head == null)||(head.next == null))
     4             return head;
     5         ListNode n = head.next;
     6         head.next = swapPairs(head.next.next);
     7         n.next = head;
     8         return n;
     9     }
    10 }
    View Code

    解法2:(Iteration迭代--每3个为一组dummy-1-2-3-4; head-dummy,n1-1,n2-2;  首先head.next-n2, 然后n1.next-n2.next, 接着n2.next = n1; 此时head-n2-n1-3-4; 所以head=n1; 开始下一对变换n1(head)-3-4;  重点是先保存head.next和head.next.next;)

    (1.dummy,next,head;  2.while(&&),n1,n2;  3.head.n-n2, n1.n-n2.n, n2.n-n1;  4.head=n1;  5.return dummy.next;)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode swapPairs(ListNode head) {
    11         ListNode dummy = new ListNode(0);
    12         dummy.next = head;
    13         head = dummy;
    14         while (head.next != null && head.next.next != null) {
    15             ListNode n1 = head.next;
    16             ListNode n2 = head.next.next;
    17             
    18             head.next = n2;
    19             n1.next = n2.next;
    20             n2.next = n1;
    21             
    22             head = n1;
    23         }
    24         return dummy.next;
    25     }
    26 }
    View Code

    61. Rotate List: https://leetcode.com/problems/rotate-list/

    向右旋转k个位置:(Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL.)

    三步:第一步index测size,得实际k;第二步滑动窗口-首先for循环移动right,然后while滑动到最后;第三步变换-三步right.next=dummy.next, dummy.next=left.next, left.next=null; 返回;

    我的解法:(和Remove Nth From End解法类似; 只需找出倒数第k个, 移到dummy后即可; 几点错误点:1.求size出错; 2.需要单独判断k=0或者size=1的情况,因为此时left和right都指向最后一个;这样left.next==null;再放到dummy后就为null了;  3.把left.next放到dummy后, right.next=head;还需要把left.next=null; 示例:k=2;left-3,right-4; ps: 过程出现了好几次bug,需要分段检查,分析原因……)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode rotateRight(ListNode head, int k) {
    11         if (head == null) return head;
    12         ListNode dummy = new ListNode(0);
    13         dummy.next = head;
    14         ListNode tmp = head;
    15         int size = 0;
    16         while (tmp != null) {
    17             tmp = tmp.next;
    18             size++;
    19         }
    20         k = k % size; 
    21         if (k == 0 || size == 1) return head;
    22         ListNode left = dummy;
    23         ListNode right = dummy;
    24         for (int i = 0; i < k; i++) {
    25             right = right.next;
    26         }
    27         while (right.next != null) {
    28             left = left.next;
    29             right = right.next;
    30         }
    31 
    32         dummy.next = left.next;
    33         left.next = null;
    34         right.next = head;
    35         return dummy.next;
    36     }
    37 }
    View Code

    改进:(把最后的dummy.next=left.next和right.next=head顺序调换即可避免left=right的特殊情况了!)

    (1.if,dummy,next;  2.tmp,size,while(!=),next,++,k;  3.left,right,for(k),right;  4.while()left,right;  5.r.n=head, dummy.n=l.n, l.n=null, return;)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode rotateRight(ListNode head, int k) {
    11         if (head == null) return head;
    12         ListNode dummy = new ListNode(0);
    13         dummy.next = head;
    14         ListNode tmp = head;
    15         int size = 0;
    16         while (tmp != null) {
    17             tmp = tmp.next;
    18             size++;
    19         }
    20         k = k % size; 
    21 
    22         ListNode left = dummy;
    23         ListNode right = dummy;
    24         for (int i = 0; i < k; i++) {
    25             right = right.next;
    26         }
    27         while (right.next != null) {
    28             left = left.next;
    29             right = right.next;
    30         }
    31         right.next = head;
    32         dummy.next = left.next;
    33         left.next = null;
    34         return dummy.next;
    35     }
    36 }
    View Code

    83. Remove Duplicates from Sorted List: https://leetcode.com/problems/remove-duplicates-from-sorted-list/

    删除重复元素:(判空;dummy;while(head.next!=null)-val等则删,否则head移动;)

    我的解法:(Test case [1,1,1]--point: 重复次数大于2, next=null; 首先要判断head.next != null; 然后while(head.val=head.next.val)-此时要删除head.next;因此head.next = head.next.next->[1,1];  此时h.val=h.n.val; 所以变成[1]因为这是在嵌套while循环中,并没有被判断h.n!=null, 就会出现h.v=h.n.v错误情况, 所以内部的while循环也要加上条件(h.n!=null); 内部while循环外, 加上判断条件(h.n!=null)时,h=h.n; [1,1,2,3,3] 当删除了3后,head.next=null了 所以head位置不变了; 注意head变化要写在嵌套while循环外,因为当有重复元素需要删除的时候, 不应该移动head;)

    (1.if(||),dummy,next;  2.while(h.n!=) while(&&)h.n=h.n.n;  3.if()h=h.n;  4.return)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode deleteDuplicates(ListNode head) {
    11         if (head == null || head.next == null) return head;
    12         ListNode dummy = new ListNode(0);
    13         dummy.next = head;
    14         while (head.next != null) {
    15             while (head.next != null && head.val == head.next.val) {
    16                 head.next = head.next.next;
    17             }
    18             if (head.next != null) 
    19                 head = head.next;
    20         }
    21         return dummy.next;
    22     }
    23 }
    View Code

    改进:(OMG 还是写得复杂了……)

    (1.if,dummy,next;  2.while(.next!=), if(h.v=h.n.v)h.n=h.n.n, else h=h.n;  3.return)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode deleteDuplicates(ListNode head) {
    11         if (head == null) {
    12             return null;
    13         }
    14         ListNode dummy = new ListNode(0);
    15         dummy.next = head;
    16         while (head.next != null) {
    17             if (head.val == head.next.val) {
    18                 head.next = head.next.next;
    19             } else {
    20                 head = head.next;
    21             }
    22         }
    23         return dummy.next;
    24     }
    25 }
    View Code

    82. Remove Duplicates from Sorted List II: https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/

    删掉重复元素的所有元素:Given 1->1->1->2->3, return 2->3.

    (判空;dummy,head;while(后两个不为null),if(val等)则定义val值,内部while(非空且值等)循环,否则移动head;

    与removeI的区别是,由于要删掉所有元素,所以head要作为前指针;具体表现是:首先head要从dummy开始;其次while循环条件是head后两个而不在是head后一个;内部while循环来删除所有节点;)

    我的解法:(1.首先判断head和h.n,为null则说明只有0或1个元素,return;  2.dummy;  3.while循环,由于需要删除重复元素的所有元素,所以head应该为前一个元素,而判断的是head.next;例如1-1-1-2-3,head是dummy, 每次以head后的三个元素为1组,所以while条件是h.n.n.n; 4.while内部,第一种情况,只有两个重复元素,例如head-2-2-3,这时候head-3即可;第二种情况,大于两个重复元素,例如head-1-1-1-1-2-3,这时候需要先删除第一个重复元素,即第二个1,再次while循环判断; 第三种情况,不重复,那么head移动;  5.while内部三种情况后还需要有一个判断,即h.n与h.n.n != null,因为执行完三种情况后可能会出现null情况(head不会出现null情况);  6.while循环外部,判断不再符合while循环的一种情况即剩下两个重复元素,将head.n=null;  7.最后return)

    (1.if,dummy;  2.while(h.n.n.n) if(h.n.v= & h.n.n.v!=) elseif(h.n.v=&h.n.n.v=) elseif(h.n.v!=)  3.if(null)return  4.if(.n.v=.n.n.v)null  5.return)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode deleteDuplicates(ListNode head) {
    11         if (head == null || head.next == null) return head;
    12         ListNode dummy = new ListNode(0);
    13         dummy.next = head;
    14         head = dummy;
    15         while (head.next.next.next != null) {
    16             if (head.next.val == head.next.next.val && head.next.next.val != head.next.next.next.val) {
    17                 head.next = head.next.next.next;
    18             } else if (head.next.val == head.next.next.val && head.next.next.val == head.next.next.next.val) {
    19                 head.next.next = head.next.next.next;
    20             } else if (head.next.val != head.next.next.val) {
    21                 head = head.next;
    22             }
    23             if (head.next == null || head.next.next == null) return dummy.next;
    24         }
    25         if (head.next.val == head.next.next.val) head.next = null;
    26         return dummy.next;
    27     }
    28 }
    View Code

    其他解法:(两个一组判断,一旦遇到重复的就保存val值,再进行一遍while循环删掉所有的元素)

    (1.if,dummy;  2.while(h.n,h.n.n);   3.if(.n.v=.n.n.v)--val,while(null,=val).n=.n.n;  4.else-head;  5.return)

     1 public class Solution {
     2     public ListNode deleteDuplicates(ListNode head) {
     3         if(head == null || head.next == null)
     4             return head;
     5         
     6         ListNode dummy = new ListNode(0);
     7         dummy.next = head;
     8         head = dummy;
     9 
    10         while (head.next != null && head.next.next != null) {
    11             if (head.next.val == head.next.next.val) {
    12                 int val = head.next.val;
    13                 while (head.next != null && head.next.val == val) {
    14                     head.next = head.next.next;
    15                 }            
    16             } else {
    17                 head = head.next;
    18             }
    19         }
    20         
    21         return dummy.next;
    22     }
    23 }
    View Code

    86. Partition List: https://leetcode.com/problems/partition-list/

    链表分成小于tar和大于tar的两部分,保留原有顺序: Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5.

    我的解法:(dummy1指向小于tar的部分,dummy2指向大于tar的部分,head遍历-指向小于tar部分的尾结点,head2指向dummy2的尾节点;小于tar时,head移动即可;大于tar时,首先判断是否是第一个数,如果是第一个,那么放到dummy2后,然后移动head2指向尾结点,判断head.n.n,head不移动,head.next变化;严重bug:Memory Limit Exceeded 原因:最后没有把head2.next=null,导致链表变成循环链表了!想了好久才发现错误。)

    (1.dummy1,dummy2,head2;  2.while(next); 3.if (>=)-if(dummy2),head2.next,head2,if(.n.n)-,else-null;  4.else;  5.head2.next,head.next,return;)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode partition(ListNode head, int x) {
            if (head == null || head.next == null) return head;
            ListNode dummy1 = new ListNode(0);
            ListNode dummy2 = new ListNode(0);
            ListNode head2 = new ListNode(0);
            dummy1.next = head;
            head = dummy1;
            while (head.next != null) {
                if (head.next.val >= x) {
                    if (dummy2.next == null) dummy2.next = head.next;
                    head2.next = head.next;
                    head2 = head2.next;
                    if (head.next.next != null) head.next = head.next.next;
                    else head.next = null;
                } else {
                    head = head.next;
                }
            }
            head2.next = null;
            head.next = dummy2.next;
            return dummy1.next;
        }
    }
    View Code

    其他解法:(leftDummy,rightDummy; left,right作为两个链表的尾结点,  head遍历;  ps:第一个dummy后的数不用单独next,可以直接用left.next;)

    (1.if;  2.leftDummy,rightDummy,left,right;  3.while() if-left,else-right,head;  4.right,left,return;)

     1 public class Solution {
     2     public ListNode partition(ListNode head, int x) {
     3         if (head == null) {
     4             return null;
     5         }
     6         
     7         ListNode leftDummy = new ListNode(0);
     8         ListNode rightDummy = new ListNode(0);
     9         ListNode left = leftDummy, right = rightDummy;
    10         
    11         while (head != null) {
    12             if (head.val < x) {
    13                 left.next = head;
    14                 left = head;
    15             } else {
    16                 right.next = head;
    17                 right = head;
    18             }
    19             head = head.next;
    20         }
    21         
    22         right.next = null;
    23         left.next = rightDummy.next;
    24         return leftDummy.next;
    25     }
    26 }
    View Code

    92. Reverse Linked List II: https://leetcode.com/problems/reverse-linked-list-ii/

    反转指定首尾的链表:

    首先dumm,head; 移动head m-1次作为前指针,left和right=head.next;移动right n-m次,此时left和right分别为首尾指针;接下来和reverseI相同,prev为right.next; 循环次数(n-m+1);最后head.next指向right/perv;返回;

    我的解法:(1-2-3-4-5,m=2,n=4; 1-4-3-2-5; 定义dummy, head指首结点的前一节点,left指向首结点,right指向尾结点。这样只需要反转链表再把反转后链表的与head和right.next相连即可;dummy-1-2-3-4-5,先让head,left,right都指向dummy. 这样便于移动指针, head-1,left-2,right-4; prev-right.next; for()循环次数为反转的次数即n-m+1; 最后head.next=right; 注意的是反转后left=right.next而不是right;所以用一个right记录还是很有必要的。)

    (1.dummy,left,right;  2.for(m-1)-head,left,for(n)-right;  3.prev,for(n-m+1),tmp,left.n,prev,left;  4.head.n,return;)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode reverseBetween(ListNode head, int m, int n) {
    11         ListNode left = new ListNode(0);
    12         ListNode right = new ListNode(0);
    13         ListNode dummy = new ListNode(0);
    14         dummy.next = head;
    15         head = dummy;
    16         left = dummy;
    17         right = dummy;
    18         for (int i = 0; i < m - 1; i++) {
    19             head = head.next;
    20         }
    21         left = head.next;
    22         for (int i = 0; i < n; i++) {
    23             right = right.next;
    24         }
    25         ListNode prev = right.next;
    26         for (int i = 0; i < n - m + 1; i++) {
    27             ListNode tmp = left.next;
    28             left.next = prev;
    29             prev = left;
    30             left = tmp;
    31         }
    32         head.next = right;
    33         return dummy.next;
    34     }
    35 }
    View Code

    稍微改进:

     1 public class Solution {
     2     public ListNode reverseBetween(ListNode head, int m, int n) {
     3         ListNode dummy = new ListNode(0);
     4         dummy.next = head;
     5         head = dummy;
     6         
     7         for (int i = 0; i < m - 1; i++) {
     8             head = head.next;
     9         }
    10         ListNode left = head.next;
    11         ListNode right = head.next;
    12         for (int i = 0; i < n - m; i++) {
    13             right = right.next;
    14         }
    15         ListNode prev = right.next;
    16         for (int i = 0; i < n - m + 1; i++) {
    17             ListNode tmp = left.next;
    18             left.next = prev;
    19             prev = left;
    20             left = tmp;
    21         }
    22         head.next = right;
    23         return dummy.next;
    24     }
    25 }
    View Code

    206. Reverse Linked List: https://leetcode.com/problems/reverse-linked-list/

    反转链表:

    解法1:迭代;prev-head-tmp三个一组;prev初始置null;while(head非null),四步-首先保存head.next=tmp, 然后head指向prev,接着移动prev和head;最后返回perv;

    解法2:递归;递归(head, prev);终止条件head=null,返回prev;三步:保存tmp,head指向prev,返回递归(tmp,head);)

    解法1:迭代Iterative (prev-head-tmp 三个一组, 变换指针并往后遍历。例如null-1-2-3, prev-null,head-1,tmp-2; 首先tmp保存head.next, 然后head->prev, 接着prev和head分别向后移动; 此时 1-null,2-3;  再迭代一次后,2-1-null,3, prev-2,head-3,tmp-3.next-null; 然后3-2-1-null, prev-3即为新的头结点, head-null跳出循环;)

    (1.prev;  2.while()-tmp,head.next,prev,head;  3.return)

     1 public class Solution {
     2     /**
     3      * @param head: The head of linked list.
     4      * @return: The new head of reversed linked list.
     5      */
     6     public ListNode reverse(ListNode head) {
     7         ListNode prev = null;
     8         while (head != null) {
     9             ListNode temp = head.next;
    10             head.next = prev;
    11             prev = head;
    12             head = temp;
    13         }
    14         return prev;
    15     }
    16 }
    View Code

    解法2:递归Recursive 

    public class Solution {
        public ListNode reverseList(ListNode head){
            return helper(head, null);
        }
        public ListNode helper(ListNode head, ListNode prev){
            if (head == null) return prev;
            ListNode tmp = head.next;
            head.next = prev;
            return helper(tmp, head);
        }
    }
    View Code

    109. Convert Sorted List to Binary Search Tree:https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/

    链表转为二叉树:

    141. Linked List Cycle:https://leetcode.com/problems/linked-list-cycle/

    判断链表是否有环:

    解法:(双指针不同速度移动, 如果有环那么fast一定会追上slow;这种解法要求slow和fast的初始位置不可以相同!因为循环条件是!=, 内部终止条件是(fast=null || next=null))

    (1.if; 2.fast,slow;  3.while(), if-return; fast,slow;  4.return)

     1 public class Solution {
     2     public boolean hasCycle(ListNode head) {
     3         if (head == null || head.next == null) return false;
     4         
     5         ListNode fast = head.next;
     6         ListNode slow = head;
     7         while (slow != fast) {
     8             if (fast == null || fast.next == null) return false;
     9             fast = fast.next.next;
    10             slow = slow.next;
    11         }
    12         return true;
    13     }
    14 }
    View Code

    类似的:(循环条件是null)

     1 public boolean hasCycle(ListNode head) {
     2     if(head==null) return false;
     3     ListNode walker = head;
     4     ListNode runner = head;
     5     while(runner.next!=null && runner.next.next!=null) {
     6         walker = walker.next;
     7         runner = runner.next.next;
     8         if(walker==runner) return true;
     9     }
    10     return false;
    11 }
    View Code

    142. Linked List Cycle II: https://leetcode.com/problems/linked-list-cycle-ii/

    返回环的首结点:(首先和cycleI相同 slow,fast;接着head和slow.next比较;

    (1-2-3-[4-5-6-7-8-9-10], 如果slow和fast都从1开始move, 当相遇时, slow移动了k步, fast移动了2k步(绕换n圈,则2k-k=nr), 相遇地点距离循环首结点距离为m;  只要head节点从首结点开始移动, 移动k-m步,  slow从meet点移动,移动k-m步; 这时候两者就在cycle首结点相遇。因为slow已经移动了k步,再移动k步就是又到了meet点,所以移动k-m步就是到cycle的首结点 ps:如果用解法1,则要求slow.next=head;因为fast多移动了一步)

    解法1:

    (1.if; 2.slow,fast; 3.while()if(),slow,fast;  4.while(slow.n) slow,head;  5.return head;)

     1 public class Solution {
     2     public ListNode detectCycle(ListNode head) {
     3         if(head == null || head.next == null) return null;
     4         ListNode slow = head;
     5         ListNode fast = head.next;
     6         while (slow != fast ) {
     7             if (fast == null || fast.next == null) return null;
     8             slow = slow.next;
     9             fast = fast.next.next;
    10         }
    11         while (head != slow.next) {
    12             head = head.next;
    13             slow = slow.next;
    14         }
    15         return head;
    16     }
    17 }
    View Code

    解法2:

     1 public class Solution {
     2             public ListNode detectCycle(ListNode head) {
     3                 ListNode slow = head;
     4                 ListNode fast = head;
     5         
     6                 while (fast!=null && fast.next!=null){
     7                     fast = fast.next.next;
     8                     slow = slow.next;
     9                     
    10                     if (fast == slow){
    11                         ListNode slow2 = head; 
    12                         while (slow2 != slow){
    13                             slow = slow.next;
    14                             slow2 = slow2.next;
    15                         }
    16                         return slow;
    17                     }
    18                 }
    19                 return null;
    20             }
    View Code

    147. Insertion Sort List: https://leetcode.com/problems/insertion-sort-list/

    插入排序:

    203. Remove Linked List Elements: https://leetcode.com/problems/remove-linked-list-elements/

    删除val值的结点:

    (1.if; 2.dummy;  3.while() if(),else;  4.return)

    public class Solution {
        public ListNode removeElements(ListNode head, int val) {
            if (head == null) return head;
            ListNode dummy = new ListNode(0);
            dummy.next = head;
            head = dummy;
            while (head.next != null) {
                if (head.next.val == val) {
                    head.next = head.next.next;
                } else {
                    head = head.next;
                }
            }
            return dummy.next;
        }
    }
    View Code

    237. Delete Node in a Linked List: https://leetcode.com/problems/delete-node-in-a-linked-list/

    删除给定节点:(change val...脑筋急转弯题……)

    1 public void deleteNode(ListNode node) {
    2     node.val=node.next.val;
    3     node.next=node.next.next;
    4 }
    View Code
  • 相关阅读:
    为Qtcreator 编译的程序添加管理员权限
    热备,冷备,云备
    最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备
    进入2012 -- 回顾我走过的编程之路
    为什么中国程序员水平一直上不了层次?无非是这些原因!
    我是如何失去团队掌控的?
    后端开发甩锅奥义
    一个线程oom,进程里其他线程还能运行吗?
    架构师必备,带你弄清混乱的JAVA日志体系!
    IDEA一定要改的八条配置
  • 原文地址:https://www.cnblogs.com/buwenyuwu/p/6208420.html
Copyright © 2011-2022 走看看