public ListNode PartitionList(ListNode node, int x)
        {
            ListNode head = node;
            ListNode tail = node;

            /* Partition list */
            while (node != null)
            {
                ListNode next = node.Next;
                if (node.Data < x)
                {
                    /* Insert node at head. */
                    node.Next = head;
                    head = node;
                }
                else
                {
                    /* Insert node at tail. */
                    tail.Next = node;
                    tail = node;
                }
                node = next;
            }
            tail.Next = null;

            return head;
        }
        public void DeleteListNode(ListNode node)
        {
            // tail node
            if (node.Next == null) return;

            ListNode temp = node.Next;
            node.Data = temp.Data;
            node.Next = temp.Next;
        }
        public void Delete_Duplicates()
        {
            ListNode l1 = new ListNode(1);
            l1.Next = new ListNode(1);
            l1.Next.Next = new ListNode(2);

            ListNode r1 = DeleteDuplicates(l1);
            Assert.AreEqual(r1.Data, 1);
            Assert.AreEqual(r1.Next.Data, 2);
        }
        public void Reverse_Linked_List()
        {
            ListNode list = new ListNode(1);
            list.Next = new ListNode(2);
            list.Next.Next = new ListNode(3);

            ListNode result = ReverseList(list);

            Assert.AreEqual(result.Data, 3 );
            Assert.AreEqual(result.Next.Data, 2);
            Assert.AreEqual(result.Next.Next.Data, 1);
        }
        public void Delete_Linked_List_Node()
        {
            ListNode l = new ListNode(1);
            l.Next = new ListNode(2);
            ListNode thirdNode = l.Next.Next = new ListNode(3);
            l.Next.Next.Next = new ListNode(4);

            DeleteListNode(thirdNode);

            Assert.AreEqual(l.Data, 1);
            Assert.AreEqual(l.Next.Data, 2);
            Assert.AreEqual(l.Next.Next.Data, 4);
        }
        public ListNode ReverseList(ListNode head)
        {
            ListNode prev = null;
            ListNode curr = null;
            ListNode next = head;

            while (next != null)
            {
                curr = next;
                next = curr.Next;
                curr.Next = prev;
                prev = curr;
            }

            return curr;
        }
        public ListNode DeleteDuplicates(ListNode head)
        {
            if (head == null || head.Next == null)
                return head;

            ListNode p = head;

            while (p != null && p.Next != null)
            {
                if (p.Data == p.Next.Data)
                    p.Next = p.Next.Next;
                else
                    p = p.Next;
            }

            return head;
        }
        public void Partition_List()
        {
            ListNode head = new ListNode(5);
            head.Next = new ListNode(4);
            head.Next.Next = new ListNode(3);
            head.Next.Next.Next = new ListNode(2);
            head.Next.Next.Next.Next = new ListNode(1);
            head.Next.Next.Next.Next.Next = new ListNode(0);

            ListNode result = PartitionList(head, 3);

            Assert.AreEqual(result.Data, 0);
            Assert.AreEqual(result.Next.Data, 1);
            Assert.AreEqual(result.Next.Next.Data, 2);
            Assert.AreEqual(result.Next.Next.Next.Data, 5);
            Assert.AreEqual(result.Next.Next.Next.Next.Data, 4);
            Assert.AreEqual(result.Next.Next.Next.Next.Next.Data, 3);
        }
        private ListNode AddTwoList2(ListNode l1, ListNode l2)
        {
            int carry = 0;

            ListNode l3 = null, head = null;

            while (l1 != null || l2 != null)
            {
                if (l1 != null)
                {
                    carry += l1.Data;
                    l1 = l1.Next;
                }

                if (l2 != null)
                {
                    carry += l2.Data;
                    l2 = l2.Next;
                }

                if (head == null)
                {
                    head = new ListNode(carry%10);
                    l3 = head;
                }
                else
                {
                    l3.Next = new ListNode(carry%10);
                    l3 = l3.Next;
                }
                carry /= 10;
            }

            if (carry == 1)
                if (l3 != null) l3.Next = new ListNode(1);

            return head;
        }
        private ListNode AddTwoList(ListNode l1, ListNode l2, int carry)
        {
            if(l1 == null && l2 == null && carry == 0)
            {
                return null;
            }

            ListNode result = new ListNode(carry);
            int value = carry;

            if (l1 != null) value += l1.Data;
            if (l2 != null) value += l2.Data;

            result.Data = value % 10;

            if (l1 != null || l2 != null)
            {
                ListNode more = AddTwoList(l1?.Next, l2?.Next, value >= 10 ? 1 : 0);
                result.Next = more;
            }

            return result;
        }
        public void Sum_Two_List()
        {
            ListNode l1 = new ListNode(2);
            l1.Next = new ListNode(4);
            l1.Next.Next = new ListNode(3);

            ListNode l2 = new ListNode(5);
            l2.Next = new ListNode(6);
            l2.Next.Next = new ListNode(4);

            // for 1st method
            ListNode result = AddTwoList(l1, l2);

            Assert.AreEqual(7, result.Data);
            Assert.AreEqual(0, result.Next.Data);
            Assert.AreEqual(8, result.Next.Next.Data);

            // for 2nd method
            ListNode result2 = AddTwoList2(l1, l2);

            Assert.AreEqual(7, result2.Data);
            Assert.AreEqual(0, result2.Next.Data);
            Assert.AreEqual(8, result2.Next.Next.Data);
        }
 public ListNode AddTwoList(ListNode l1, ListNode l2)
 {
     return AddTwoList(l1, l2, 0);
 }