Linked list 链表完整笔记
Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
思路:
1.找到中点
2.把中点后的链表反转
3.把2部分链表merge起来
注意把middle.next = null
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public void reorderList(ListNode head) { if (head == null || head.next == null) { return; } ListNode mid = findMiddle(head); ListNode tail = reverseList(mid.next); //keng mid.next = null; combine(head, tail); } //step 1 find middle private static ListNode findMiddle(ListNode head) { ListNode slow, fast; slow = head; fast = head; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } //step 2 reverse the list after the middle node private static ListNode reverseList(ListNode head) { ListNode newHead = null; while (head != null) { ListNode temp = head.next; head.next = newHead; newHead = head; head = temp; } return newHead; } //step 3 conbine two list private static void combine(ListNode head, ListNode tail) { while (head != null && tail != null ) { ListNode tempHead = head.next; ListNode tempTail = tail.next; head.next = tail; tail.next = tempHead; tail = tempTail; head = head.next.next; } } }
九章的代码
在merge部分,利用的%2的方式,一次取1个点出来
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
-----------------------------------------------------------
sort list
merge sort, 用divide and conquer的方式,先把list分为左右部分,然后排序后合并
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 sortList(ListNode head) { 11 if (head == null) { 12 return head; 13 } 14 return helper(head); 15 } 16 private ListNode helper(ListNode head) { 17 // step 1, divide 18 if (head == null || head.next == null) { 19 return head; 20 } 21 //find the mid point and need to set mid.next = null! 22 ListNode mid = findMiddle(head); 23 ListNode right = sortList(mid.next); 24 mid.next = null; 25 ListNode left = sortList(head); 26 return merge(left, right); 27 28 } 29 30 private ListNode merge (ListNode left, ListNode right) { 31 // step 2 conqure 32 ListNode dummy = new ListNode(0); 33 ListNode current = dummy; 34 35 while (left != null || right != null) { 36 while (left != null && right != null) { 37 if (left.val >= right.val) { 38 current.next = right; 39 right = right.next; 40 } else { 41 current.next = left; 42 left = left.next; 43 } 44 current = current.next; 45 } 46 if (left != null) { 47 current.next = left; 48 left = null; 49 } 50 if (right != null) { 51 current.next = right; 52 right = null; 53 } 54 } 55 return dummy.next; 56 } 57 58 private ListNode findMiddle(ListNode head) { 59 ListNode fast = head.next; 60 ListNode slow = head; 61 while (fast != null && fast.next != null) { 62 fast = fast.next.next; 63 slow = slow.next; 64 } 65 return slow; 66 } 67 68 }
quick sort
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
-----------------------------------------------------------
Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
双指针法:
1. 找到两条链表的长度
2. 长的链表先把current向前走长度差个单位
3.两个指针一起往后走,知道相等就打断
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { int lengthA = getLength(headA); int lengthB = getLength(headB); int dis = Math.abs(lengthA -lengthB); ListNode fast = lengthA >= lengthB ? headA : headB; ListNode slow = lengthA >= lengthB ? headB : headA; for (int i = 0; i < dis; i++) { fast = fast.next; } while (fast != null && slow != null) { if (fast.val == slow.val) { return fast; } fast = fast.next; slow = slow.next; } return null; } private static int getLength(ListNode head) { int len = 0; while (head != null) { head = head.next; len++; } return len; } }