Exemple #1
0
        /// <summary>
        /// ReverseLinkedListInGroupsOfGivenSizeV2 (Using Stack), TC: O(n*groupsize), SC: O(groupSize)
        /// This is done via Stack and that's why takes more space.
        /// https://www.geeksforgeeks.org/reverse-linked-list-groups-given-size-set-2/
        ///
        /// It's previous attempt for better SC is in the file below.
        /// Method: ReverseLinkedListInGroupsOfGivenSize, TC: O(n*groupsize), SC: O(1)
        /// https://www.geeksforgeeks.org/reverse-a-list-in-groups-of-given-size/
        /// </summary>
        public void ReverseLinkedListInGroupsOfGivenSizeV2()
        {
            var list = LLUtility.CreateSinglyLinkedList(new int[] { 1, 2, 2, 4, 5, 6, 7, 8 });

            var head     = list.Head;
            var flag     = true;
            var tempNode = head;
            var size     = 4;
            var stack    = new Stack <ISinglyNode <int> >();
            ISinglyNode <int> tempNode2 = null;

            // iterate while your first moving temp node is valid
            while (tempNode != null)
            {
                // push elements in stack based on group size.
                for (int i = 0; i < size; i++)
                {
                    if (tempNode != null)
                    {
                        stack.Push(tempNode);
                        tempNode = tempNode.Next;
                    }
                    // if elements perish before group iteration completes, then come out.
                    else
                    {
                        break;
                    }
                }

                // We'll now pull out elements from stack to point to Head to begin
                // and then iterate through another temp node till we connect all stack
                // elements in reverse order. Post that, connect reversed list's END
                // to remaining "initial" list that still needs to be reversed.
                while (stack.Any())
                {
                    // Realign HEAD only once.
                    if (flag)
                    {
                        head      = stack.Pop();
                        tempNode2 = head;
                        flag      = false;

                        // Realigned HEAD now should point to the list.
                        list.Head = head;
                    }
                    else
                    {
                        tempNode2.Next = stack.Pop();
                        tempNode2      = tempNode2.Next;
                    }
                }

                // Now, connect reversed list's END
                // to remaining "initial" list that still needs to be reversed.
                tempNode2.Next = tempNode;

                list.Print();
            }
        }
        // Add element at end
        public void AddAtEnd(ISinglyNode <T> node)
        {
            if (Head == null)
            {
                Last = Head = node;
            }
            else
            {
                Last.Next = node;
                Last      = node;
            }

            Count++;
        }
        /// <summary>
        /// ReverseLinkedListPostNnodes, TC: O(n), SC: O(1)
        /// </summary>
        public static void ReverseLinkedListPostNnodes()
        {
            var list = LLUtility.CreateSinglyLinkedList(new int[] { 1, 2, 3, 4, 5, 6 }.Cast <int>());
            int counter = 2, index = 0; // reverse after 2 nodes

            list.Print();

            var node = list.Head;
            ISinglyNode <int> intervalLinkNode = null, previous = null, current = null;

            // Save the node after which you will reverse your list.
            // and mark the next two nodes as previous and current
            // for reversal process
            while (node != null)
            {
                if (index == counter - 1)
                {
                    intervalLinkNode = node;
                    previous         = intervalLinkNode.Next;
                    current          = previous.Next;
                    break;
                }

                node = node.Next;
                index++;
            }

            ISinglyNode <int> next = null;

            while (current != null)
            {
                next         = current.Next;
                current.Next = previous;

                if (next == null)
                {
                    // Reset the interval node's NEXT element to NULL AS END
                    // set the interval's NEXT as the current element which is actually last
                    intervalLinkNode.Next.Next = null;
                    intervalLinkNode.Next      = current;
                    break;
                }

                previous = current;
                current  = next;
            }

            list.Print();
        }
Exemple #4
0
        /// <summary>
        /// AddTwoNumbersContainedInLinkedLists
        ///
        /// Question: You are given two non-empty linked lists representing
        /// two non-negative integers. The digits are stored in reverse order
        /// and each of their nodes contain a single digit. Add the two
        /// numbers and return it as a linked list.
        /// You may assume the two numbers do not contain any leading zero, except the number 0 itself.
        ///
        /// LeetCode Question
        /// https://leetcode.com/problems/add-two-numbers/
        /// Type: LinkedList
        /// Difficulty: Medium
        /// </summary>
        public void AddTwoNumbersContainedInLinkedLists()
        {
            var l1 = LLUtility.CreateSinglyLinkedList(new int[] { 2, 4, 3 }).Head;
            var l2 = LLUtility.CreateSinglyLinkedList(new int[] { 5, 6, 4 }).Head;

            // Initialise it with 0 so we don't have to make flags for checking and iteration.
            // We'll just provide the output with next node instead.
            var sum = new SinglyNode <int>(0);

            int temp, q;

            temp = q = 0;
            ISinglyNode <int> sumPointer = sum;

            // checking the pointer with current digits. If both of them are null means numbers are finished.
            while (l1 != null || l2 != null)
            {
                // scan for nullables because numbers may not be of same length. If they aren't,
                // and one number finishes early then just replace it with 0 and don't hamper the addition
                temp = (l1?.Value ?? 0) + (l2?.Value ?? 0) + q;
                q    = temp / 10;                                  // carry

                sumPointer.Next = new SinglyNode <int>(temp % 10); // remainder goes as new node (actually sum of the nums)
                sumPointer      = sumPointer.Next;                 // move it ahead to store the next remainder in the next iteration

                // move the pointer to next digits. Nullable is used since both the numbers may not be of same length.
                l1 = l1?.Next;
                l2 = l2?.Next;
            }

            // accomodate quotient/carry if it spills over. E.g. 11 > 1  1
            if (q > 0)
            {
                sumPointer.Next = new SinglyNode <int>(q);
            }

            //Return or Print the sum now..
            var list = new SinglyLinkedList <int>();

            list.Head = sum.Next;
            list.Print();
        }
        /// <summary>
        /// FindMiddleElement, TC: O(n), SC: O(1)
        /// </summary>
        public static void FindMiddleElement()
        {
            var linkedList = LLUtility.CreateSinglyLinkedList(new int[] { 1, 2, 3, 4, 5, 6, 7 }.Cast <int>());

            // look for middle element now
            var node = linkedList.Head;
            ISinglyNode <int> middleNode = null;
            var flag = true;

            while (node != null)
            {
                if (flag)
                {
                    middleNode = middleNode == null ? linkedList.Head : middleNode.Next;
                }

                flag = !flag;
                node = node.Next;
            }

            Console.WriteLine(middleNode.Value);
        }
        /// <summary>
        /// RotateLinkedList, TC: O(n), SC: O(1)
        /// </summary>
        public static void RotateLinkedList()
        {
            var list = LLUtility.CreateSinglyLinkedList(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }.Cast <int>());

            Console.WriteLine("Original Linked List");
            list.Print();
            int toBeRotated = 3, counter = 0;

            Console.WriteLine($"Rotation count: {toBeRotated}\n");

            ISinglyNode <int> newLastNode = null, node = list.Head;

            // Iterate till we reach last node
            while (node.Next != null)
            {
                // Save the node which is to be made LAST
                if (counter == toBeRotated - 1)
                {
                    newLastNode = node;
                }

                node = node.Next;
                counter++;
            }

            // Last node is the new linking node.
            var linkingNode = node;

            // 1. Link the last node to old HEAD now.
            // 2. Reset the HEAD to new node.
            // 3. Set NEW LAST NODE's next to NULL
            linkingNode.Next = list.Head;
            list.Head        = newLastNode.Next;
            newLastNode.Next = null;

            list.Print();
        }