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 }
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 }
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 }
改进:(当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 }
解法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 }
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 }
解法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 }
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 }
改进:(把最后的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 }
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 }
改进:(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 }
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 }
其他解法:(两个一组判断,一旦遇到重复的就保存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 }
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; } }
其他解法:(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 }
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 }
稍微改进:
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 }
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 }
解法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); } }
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 }
类似的:(循环条件是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 }
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 }
解法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 }
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; } }
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 }