Example #1
0
        public void Test1()
        {
            Node A = new Node(1);

            Assert.AreEqual(true, _07.CheckLinkedListPalindromeUsingStack(A));
            Assert.AreEqual(true, _07.CheckLinkedListPalindromeRecursive(A, 1).isPalindrome);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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;
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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();
        }
Example #8
0
        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);
        }
Example #9
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;
        }
Example #10
0
        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();
        }
Example #11
0
        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();
        }
Example #12
0
        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;
        }
Example #13
0
        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);
        }
Example #14
0
        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);
        }
Example #15
0
        /*
         * ! - 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;
        }
Example #16
0
        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;
            }
        }
Example #17
0
        /*
         * 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;
        }
Example #18
0
        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;
        }
Example #19
0
        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;
        }
Example #20
0
        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;
        }
Example #21
0
 public CheckLinkedListPalindromeRecursiveHelper(Node node, bool isPalindrome)
 {
     this.node = node;
     this.isPalindrome = isPalindrome;
 }