public static bool AreEqual(Node n1, Node n2) { if(n1 == null && n2 == null) { return true; } if(n1 == null || n2 == null) { return false; } while(n1 != null && n2 != null) { if(n1.Data != n2.Data) { return false; } n1 = n1.Next; n2 = n2.Next; } if ((n1 == null && n2 == null) == false) { return false; } return true; }
public static int GetLength(Node node) { int length = 0; while(node != null) { length++; node = node.Next; } return length; }
public bool Test() { bool result = true; // Test Case: null Node n = null; RemoveDuplicates(n); result &= n == null; // Test Case: One element n = new Node(1); RemoveDuplicates(n); result &= n.Data == 1 && n.Next == null; // Test Case: n elements with same value should result in 1 var a1 = new int[] { 1, 1, 1, 1, 1, 1 }; n = Node.CreateLinkedList(a1); RemoveDuplicates(n); result &= n.Data == 1 && n.Next == null; // No dupes var a2 = new int[] { 1, 2, 3, 4, 5, 6, 7, 0, 9, 8 }; n = Node.CreateLinkedList(a2); RemoveDuplicates(n); result &= Node.GetLength(n) == 10; // Another test case with random data and a dupe at beginnnig and end var a3 = new int[] { 1, 2, 1, 3, 2, 1, 3, 5, 4, 6, 7, 6, 6, 1, 3, 4, 7 }; n = Node.CreateLinkedList(a3); RemoveDuplicates_HashTable(n); result &= Node.GetLength(n) == 7; return result; }
public static Node CreateLinkedList(int[] array) { if(array == null || array.Length == 0) { return null; } Node head = new Node(array[0]); Node cursor = head; for(int i = 1; i < array.Length; i++) { cursor.Next = new Node(array[i]); cursor = cursor.Next; } return head; }
private Node FindKthToLastRecursive(Node node, int k) { int i = 0; return FindKthToLast(node, k, ref i); }
private Node FindKthToLast(Node current, int k, ref int i) { if(current == null) { return null; } var result = FindKthToLast(current.Next, k, ref i); i++; if(i == k) { return current; } return result; }
private Node FindKthToLast(Node head, int k) { Node p1 = head, p2 = head; if(head == null) { return null; } // Move p2 by k elements int i = 0; while(p2 != null && i < k) { p2 = p2.Next; i++; } // If p2 is already null, then k is actually longer than the list, so return null // The only exception is when the linked list is exactly the size of k, in which case // p2 becomes null after the k iterations but we should still return p1, so if 'i' is still // less than k, we know that list is definitely shorter than k if(i < k) { return null; } while(p2 != null) { p2 = p2.Next; p1 = p1.Next; } return p1; }
public bool Test() { bool result = true; // Test Case: null int x = 3; Node node = null; Node pNode = PartitionInPlace(node, x); result &= pNode == null; // Test Case: x is around the middle var array = new int[] { 1, 2, 4, 3, 4, 2, 4, 1 }; node = Node.CreateLinkedList(array); pNode = PartitionInPlace(node, x); result &= IsPartitioned(pNode, x); // Test Case: All values are lower than x x = 5; node = Node.CreateLinkedList(array); pNode = PartitionInPlace(node, x); result &= IsPartitioned(pNode, x); // Test Case: All values are greater than or equal to x x = 1; node = Node.CreateLinkedList(array); pNode = PartitionInPlace(node, x); result &= IsPartitioned(pNode, x); // Test Case: One element that is lower than x node = new Node(0); pNode = PartitionInPlace(node, x); result &= IsPartitioned(pNode, x); // Test Case: One element that is greater than x node = new Node(2); pNode = PartitionInPlace(node, x); result &= IsPartitioned(pNode, x); return result; }
private Node PartitionInPlace(Node node, int pivot) { // Create new virtual pivot node Node pivotNode = new Node(pivot); // Create new virtual head node. // For the case when the first node is greater than or equal to pivot Node headNode = new Node(); headNode.Next = node; Node next = node, beforeLeft = headNode, beforeRight = null; while(next != null) { next = next.Next; node.Next = null; if(node.Data < pivot) { beforeLeft.Next = node; beforeLeft = beforeLeft.Next; beforeLeft.Next = pivotNode; } else { if(beforeRight == null) { beforeRight.Next = beforeRight = node; } else { beforeRight.Next = node; beforeRight = beforeRight.Next; } } node = next; } // Remove the pivot node beforeLeft.Next = pivotNode.Next; // Extra node at head is auto-removed since there is no reference to it outside this method. return headNode.Next; }
// This solution is taken from https://github.com/gaylemcd/ctci/blob/master/c-sharp/Chapter02/Q02_4.cs // It fails if the input list doesn't contain the pivot value private Node Partition4(Node listHead, int pivot) { Node leftSubList = null; Node rightSubList = null; Node rightSubListHead = null; Node pivotNode = null; var currentNode = listHead; while (currentNode != null) { var nextNode = currentNode.Next; currentNode.Next = null; if (currentNode.Data < pivot) { leftSubList = leftSubList == null ? currentNode : leftSubList = leftSubList.Next = currentNode; } else if (currentNode.Data > pivot) { rightSubList = rightSubList == null ? rightSubListHead = currentNode : rightSubList = rightSubList.Next = currentNode; } else { pivotNode = currentNode; } currentNode = nextNode; } pivotNode.Next = rightSubListHead; rightSubListHead = pivotNode; leftSubList.Next = rightSubListHead; return listHead; }
// This solution is taken from https://github.com/gaylemcd/ctci/blob/master/c-sharp/Chapter02/Q02_4.cs Node Partition2(Node node, int pivot) { Node beforeStart = null; Node afterStart = null; /* Partition list */ while (node != null) { var next = node.Next; if (node.Data < pivot) { /* Insert node into start of before list */ node.Next = beforeStart; beforeStart = node; } else { /* Insert node into front of after list */ node.Next = afterStart; afterStart = node; } node = next; } /* Merge before list and after list */ if (beforeStart == null) { return afterStart; } var head = beforeStart; while (beforeStart.Next != null) { beforeStart = beforeStart.Next; } beforeStart.Next = afterStart; return head; }
// This solution is taken from https://github.com/gaylemcd/ctci/blob/master/c-sharp/Chapter02/Q02_4.cs Node Partition(Node node, int pivot) { Node beforeStart = null; Node beforeEnd = null; Node afterStart = null; Node afterEnd = null; /* Partition list */ while (node != null) { var next = node.Next; node.Next = null; if (node.Data < pivot) { if (beforeStart == null) { beforeStart = node; beforeEnd = beforeStart; } else { beforeEnd.Next = node; beforeEnd = node; } } else { if (afterStart == null) { afterStart = node; afterEnd = afterStart; } else { afterEnd.Next = node; afterEnd = node; } } node = next; } /* Merge before list and after list */ if (beforeStart == null) { return afterStart; } beforeEnd.Next = afterStart; return beforeStart; }
private bool IsPartitioned(Node node, int x) { if(node == null) { return true; } // Move past all the nodes that are less than x while(node != null && node.Data < x) { node = node.Next; } // Move past all the nodes that are greater than or equal to x while(node != null && node.Data >= x) { node = node.Next; } if(node == null) { return true; } return false; }
private void RemoveDuplicates(Node head) { Node a = head; Node b; while(a != null) { b = a; while(b.Next != null) { Node c = b.Next; if(c != null && c.Data == a.Data) { b.Next = c.Next; } else { b = b.Next; } } a = a.Next; } }
private Node PartitionNewCopy(Node head, int x) { Node beforeFirst = null, beforeLast = null, afterFirst = null, temp = null; while(head != null) { if(head.Data < x) { temp = beforeLast; beforeLast = new Node(head.Data); if(temp != null) { temp.Next = beforeLast; } else { beforeFirst = beforeLast; } } else { temp = afterFirst; afterFirst = new Node(head.Data); afterFirst.Next = temp; } head = head.Next; } if(beforeLast == null) { return afterFirst; } else { beforeLast.Next = afterFirst; return beforeFirst; } }
public static void PrintList(Node node) { while(node != null) { Console.Write("{0}\t", node.Data); node = node.Next; } Console.WriteLine(); }
private void RemoveDuplicates_HashTable(Node head) { if(head == null || head.Next == null) { return; } Node current = head.Next, previous = head; HashSet<int> hashSet = new HashSet<int>(); hashSet.Add(head.Data); while(current != null) { // Found a duplicate if(hashSet.Contains(current.Data)) { previous.Next = current.Next; } else { hashSet.Add(current.Data); previous = current; } current = current.Next; } }