public static ListNode RemoveNthFromEnd(ListNode head, int n) { if (head == null) return head; ListNode fast = head; int visit = 0; while (visit < n) { if (fast == null) break; fast = fast.next; visit++; } if (visit < n) throw new ArgumentOutOfRangeException("n is too large"); // find the target node ListNode prev = new ListNode(0); prev.next = head; ListNode slow = head; while (fast != null) { slow = slow.next; fast = fast.next; prev = prev.next; } // delete prev.next = slow.next; return slow != head ? head : head.next; }
private ListNode Reverse(ListNode head, ListNode reversed) { if (head == null) return reversed; ListNode next = head.next; head.next = reversed; return Reverse(next, head); }
public static void PrintLinkedList(ListNode head) { while (head != null) { Console.Write(head.val.ToString() + "->"); head = head.next; } Console.Write("NULL\n"); }
public ListNode DeleteDuplicates(ListNode head) { if (head == null || head.next == null) return head; ListNode dummy = new ListNode(0); dummy.next = head; ListNode prev = dummy; ListNode curr = head; while (curr != null) { // skip duplicates while (curr.next != null && curr.next.val == curr.val) curr = curr.next; // delete if (prev.next != curr) { prev.next = curr.next; } else { // curr is not duplicates prev = prev.next; } curr = curr.next; } return dummy.next; }
public ListNode RotateRight(ListNode head, int k) { if (head == null || k == 0) return head; ListNode fake = new ListNode(0); fake.next = head; ListNode front = fake; // get ending node and the total size int i = 0; while (front.next != null) { front = front.next; i++; } k = k % i; // effective rotation number // cut point ListNode rear = fake; for (int j = 0; j < i - k; j++) { rear = rear.next; } front.next = fake.next; fake.next = rear.next; rear.next = null; return fake.next; }
private int GetLength(ListNode head) { int len = 0; while (head != null) { len++; head = head.next; } return len; }
//--------------------------------------------------------------------- // One pass method: make cycle public ListNode GetIntersectionNode_M2(ListNode headA, ListNode headB) { ListNode A = headA; ListNode B = headB; while (A != B) { A = A == null ? headB : A.next; B = B == null ? headA : B.next; } return A; }
// Question #141 public static bool HasCycle(ListNode head) { ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) return true; } return false; }
// Iterative method public ListNode MakeReverseIteration(ListNode head) { ListNode fake = null; ListNode curr = head; ListNode prev = fake; while (curr != null) { ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; }
// #148 public ListNode SortLinkedList(ListNode head) { if (head == null || head.next == null) return head; // find out mid point ListNode fast = head.next.next; ListNode slow = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } ListNode second = SortLinkedList(slow.next); slow.next = null; return Merge(SortLinkedList(head), second); }
public ListNode MergeKLists(ListNode[] lists) { int N = lists.Length; int start = 0; int end = N - 1; while (end > 0) { start = 0; while (start < end) { // merger two lists lists[start] = Merge2Lists(lists[start], lists[end]); // save result to start start++; end--; } } return N > 0 ? lists[0] : null; }
// Three passes method public ListNode GetIntersectionNode_M1(ListNode headA, ListNode headB) { int lenA = GetLength(headA); int lenB = GetLength(headB); int diff = Math.Abs(lenA - lenB); ListNode fast = lenB > lenA ? headB : headA; ListNode slow = fast == headB ? headA : headB; while (diff > 0) { fast = fast.next; diff--; } while (fast != slow) { fast = fast.next; slow = slow.next; } return fast; }
private ListNode Merge2Lists(ListNode l1, ListNode l2) { ListNode fake = new ListNode(0); ListNode curr = fake; while (l1 != null && l2 != null) { if (l1.val < l2.val) { curr.next = l1; l1 = l1.next; } else { curr.next = l2; l2 = l2.next; } curr = curr.next; } ListNode r = l1 == null ? l2 : l1; curr.next = r; return fake.next; }
// Question #142 public static ListNode DetectCycle(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (slow == fast) { break; } } // no cycle if (fast == null || fast.next == null) return null; slow = head; // meet at the cycle starting node while (slow != fast) { slow = slow.next; fast = fast.next; } return slow; }
// merge two sorted list private ListNode Merge(ListNode a, ListNode b) { ListNode dummy = new ListNode(0); // node before head ListNode p = dummy; while (a != null && b != null) { if (a.val < b.val) { p.next = a; a = a.next; } else { p.next = b; b = b.next; } p = p.next; } ListNode remain = a == null ? b : a; p.next = remain; ListNode head = dummy.next; dummy = null; return head; }
//------------------------------------------------------------------ // Recursive method public ListNode MakeReverseRecursion(ListNode head) { return Reverse(head, null); }