public void Test1() { Node A = new Node(1); Assert.AreEqual(true, _07.CheckLinkedListPalindromeUsingStack(A)); Assert.AreEqual(true, _07.CheckLinkedListPalindromeRecursive(A, 1).isPalindrome); }
public static Node DeleteNthLastElement(Node head, int posFromLast) { Node p1 = head; Node p2 = head; while (p1.next != null) { if (posFromLast <= 0) { p2 = p2.next; } p1 = p1.next; posFromLast--; } if (posFromLast > 0) { return head.next; } else { p2.next = p2.next.next; return head; } }
public static void DeleteNodeGivenNode(Node node) { if (node == null || node.next == null) { throw new ElementOutOfBoundsException(); } node.value = node.next.value; node.next = node.next.next; }
public void Test2() { Node A = new Node(1); Node B = new Node(2); Node C = new Node(1); A.next = B; B.next = C; Assert.AreEqual(true, _07.CheckLinkedListPalindromeUsingStack(A)); Assert.AreEqual(true, _07.CheckLinkedListPalindromeRecursive(A, 3).isPalindrome); }
public void TestReverse() { Node n1 = new Node(9); n1.next = new Node(9); n1.next.next = new Node(9); Node n2 = new Node(9); n2.next = new Node(9); n2.next.next = new Node(9); Node result = _05.AddLinkedListReverse(n1, n2); }
public void TestForward() { Node n1 = new Node(9); n1.next = new Node(9); n1.next.next = new Node(9); Node n2 = new Node(9); n2.next = new Node(9); n2.next.next = new Node(9); n2.next.next.next = new Node(9); Node result = _05.AddLinkedListForward(n1, n2); }
public void Test1() { Node head = new Node(2); Node ptr = head; foreach (int num in new int[] {8, 9, 2, 1, 9, 9, 5, 5, 7, 0}){ ptr.next = new Node(num); ptr = ptr.next; } head.PrintTail(); _01.RemoveDuplicates(head); head.PrintTail(); }
public void TestRecursive() { Node n1 = new Node(9); n1.next = new Node(9); n1.next.next = new Node(9); Node n2 = new Node(9); n2.next = new Node(9); n2.next.next = new Node(9); n2.next.next.next = new Node(9); Node result = _05.RecursiveReverse(n1, n2, 0); }
// Stack can be used to reverse a linked list public static Node AddLinkedListForward(Node l1, Node l2) { Stack<int> stack1 = new Stack<int>(); Stack<int> stack2 = new Stack<int>(); while (l1 != null) { stack1.Push(l1.value); l1 = l1.next; } while (l2 != null) { stack2.Push(l2.value); l2 = l2.next; } // after reversing the list with a stack it's essentially the same concept as before int carry = 0; int sum; Node head = null; while (stack1.Count != 0 || stack2.Count != 0) { if (stack1.Count > 0 && stack2.Count > 0) { sum = stack1.Pop() + stack2.Pop() + carry; } else if (stack1.Count > 0) { sum = stack1.Pop() + carry; } else { sum = stack2.Pop() + carry; } Node newNode = new Node(sum % 10); carry = sum / 10; newNode.next = head; head = newNode; } if (carry == 1) { Node newNode = new Node(1); newNode.next = head; head = newNode; } return head; }
public void Test2() { Node head = new Node(1); Node ptr = head; foreach (int num in new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }) { ptr.next = new Node(num); ptr = ptr.next; } head.PrintTail(); _01.RemoveDuplicates(head); head.PrintTail(); }
public void Test() { Random rand = new Random(); Node head = new Node(rand.Next(0, 10)); Node ptr = head; for (int i = 0; i < 10; i++) { ptr.next = new Node(rand.Next(0, 10)); ptr = ptr.next; } head.PrintTail(); _01.RemoveDuplicates(head); head.PrintTail(); }
public static Node PartitionList(Node node, int x) { Node leftHead = null; Node left = null; Node rightHead = null; Node right = null; while (node != null) { if (node.value <= x) { if (leftHead == null) { leftHead = node; left = node; } else { left.next = node; left = left.next; } } else { if (rightHead == null) { rightHead = node; right = node; } else { right.next = node; right = right.next; } } node = node.next; } if (left != null) { left.next = rightHead; return leftHead; } return rightHead; }
public void Test() { Node A = new Node(1); Node B = new Node(2); Node C = new Node(3); Node D = new Node(4); Node E = new Node(5); Node F = new Node(6); A.next = B; B.next = C; C.next = D; D.next = E; E.next = F; F.next = D; Node result = _06.BeginningOfLoop(A); }
public void Test() { Node A = new Node(1); Node B = new Node(2); Node C = new Node(3); Node D = new Node(3); Node E = new Node(2); Node F = new Node(1); A.next = B; B.next = C; C.next = D; D.next = E; E.next = F; Assert.AreEqual(true, _07.CheckLinkedListPalindromeUsingStack(A)); Assert.AreEqual(true, _07.CheckLinkedListPalindromeRecursive(A, 6).isPalindrome); }
/* * ! - Exclamation point denotes collision point * [A!] -> B -> C -> [A] | collision point 0 away from beginning of loop A * BEFORE LOOP (empty) * A -> [B] -> C -> D! -> [B] | collision point 1 away from beginning of loop B * - BEFORE LOOP size = 1 * A -> B -> [C] -> D! -> E -> [C] | collision point 2 away from beginning of loop C * ------ BEFORE LOOP size = 2 * A -> B -> C -> [D!] -> E -> F -> [D] | collision point 0 away from beginning of loop D * ----------- BEFORE LOOP size = 3 * A -> B -> C -> D -> [E] -> F -> G! -> [E] | collision point 1 away from beginning of loop E * ---------------- BEFORE LOOP size = 4 * * We can then essentially deduce BEFORE_LOOP % LOOP_SIZE = how far the collision away is from the beginning. * Since we know there must be a loop, BEFORE LOOP must be a multiple of how far away the collision point is from the beginning of the loop (or the collision point would be in a different spot). * Then we can simply run a pointer from BEFORE LOOP and then continue a pointer from collision point, and the place they collide is the beginning of the loop. * * More formally: when the slower pointer takes k steps, the faster pointer will have taken 2k steps. Therefore, the collision would have happened at 2k - k (or k steps). * When the slower pointer is 0 steps into the loop, the faster pointer will be k % LOOP_SIZE (K from now on) steps into the loop. * The slower pointer is thus LOOP_SIZE - K distance from the faster pointer. * Since both pointers are now in a circle, the faster pointer will approach the slower pointer at a rate of 1 node per step. * Since K is just k % LOOP_SIZE, another pointer sent from the beginning of the list will collide with a pointer resumed from the start of the list, as both are K away from the beginning of the list. * */ public static Node BeginningOfLoop(Node head) { Node p1 = head; // step by 1 Node p2 = head; // step by 2 do { p1 = p1.next; p2 = p2.next.next; } while (p1 != p2); // This is where they collide p2 = head; // Move to start of list, now move by 1 while (p1 != p2) { p1 = p1.next; p2 = p2.next; } return p1; }
public static void RemoveDuplicates(Node head) { Node ptr = head.next; while (ptr != null) { Node search = head; while (search != ptr) { // found something, remove value from list if (search.value == ptr.value) { while (search.next != ptr) { search = search.next; } search.next = ptr.next; break; } search = search.next; } ptr = ptr.next; } }
/* * For recursive implementation, first we should consider the base cases: * 0: obvious * 1: ( A ( B ) A ) - B does not need to be compared, so A goes with B.next * 2: ( A ( B1 B2 ) A ) - Though this doesn't seem like a base case (why not use 0)? It is. * The reason is that if we use 0, instead of comparing B1 B2 we will compare: * n = A, length = 4 * n = B1, length = 2 * n = B2, length = 0 -> return value is B2.next which is A * -> n = B1 will end up getting compared to return value B2.next A * * The next key thing is that the input is the first half of the list, and the return value is the second half. * Now you can compare (due to recursive calls) the 0 with n, 1 with n-1, 2 with n-2, etc... * * Since we use the return value to get the second half of the list, we need to wrap the return node in a class * with a boolean result so that we can give an answer at the end. */ public static CheckLinkedListPalindromeRecursiveHelper CheckLinkedListPalindromeRecursive(Node n, int length) { if (length == 0 || n == null) { return new CheckLinkedListPalindromeRecursiveHelper(null, true); } if (length == 1) { return new CheckLinkedListPalindromeRecursiveHelper(n.next, true); } if (length == 2) { return new CheckLinkedListPalindromeRecursiveHelper(n.next.next, n.value == n.next.value); } CheckLinkedListPalindromeRecursiveHelper res = CheckLinkedListPalindromeRecursive(n.next, length - 2); if (!res.isPalindrome) { return res; } else if (n.value != res.node.value) { res.isPalindrome = false; return res; } res.node = res.node.next; return res; }
public static bool CheckLinkedListPalindromeUsingStack(Node head) { Stack<int> stack = new Stack<int>(); Node ptr = head; while (ptr != null) { stack.Push(ptr.value); ptr = ptr.next; } ptr = head; int numToCompare = stack.Count / 2; for (int i = 0; i < numToCompare; i++) { if (stack.Pop() != ptr.value) { return false; } ptr = ptr.next; } return true; }
public static Node RecursiveReverse(Node l1, Node l2, int carry) { int sum = 0; if (l1 == null && l2 == null) { sum += carry; if (sum == 0) { return null; } } else if (l1 == null) { sum = l2.value + carry; } else if (l2 == null) { sum = l1.value + carry; } else { sum = l1.value + l2.value + carry; } Node rest = RecursiveReverse(l1 == null ? null : l1.next, l2 == null ? null : l2.next, sum / 10); Node newNode = new Node(sum % 10); newNode.next = rest; return newNode; }
public static Node AddLinkedListReverse(Node l1, Node l2) { Node headNode = new Node(0); Node prevNode = headNode; int carry = 0; while (l1 != null || l2 != null) { Node newNode = new Node(); // 3 cases if (l1 == null) // l1 is null, add l2 with any possible carry and go to next node { newNode.value = l2.value + carry; l2 = l2.next; } else if (l2 == null) // l2 is null, add l1 with any possible carry and go to next node { newNode.value = l1.value + carry; l1 = l1.next; } else // add both numbers and go to next node { newNode.value = l1.value + l2.value + carry; l1 = l1.next; l2 = l2.next; } // if the number has carry can be calculated by dividing the value by 10 since division is rounding towards 0 carry = newNode.value / 10; // value can be calculated from the modulus newNode.value = newNode.value % 10; // set the next node prevNode.next = newNode; prevNode = prevNode.next; } // perform the last carry if (carry == 1) { Node newNode = new Node(); newNode.value = carry; prevNode.next = newNode; } return headNode.next; }
public CheckLinkedListPalindromeRecursiveHelper(Node node, bool isPalindrome) { this.node = node; this.isPalindrome = isPalindrome; }