コード例 #1
0
        public static bool IsPalindrome(IntNode head)
        {
            if (head == null)
            {
                return(false);
            }

            // Traverse the list to count n
            var nodeListLength = head.GetListLength();

            if (nodeListLength == 1)
            {
                return(true);
            }

            // n == 2
            // true iff elements are equal
            //// Two node base case (not necessary)
            //if (nodeListLength == 2)
            //    {
            //        if (head.Data != head.Next.Data)
            //            return false;
            //    }
            //    // Three node base case (not necessary)
            //    if (nodeListLength == 3)
            //    {
            //        if (head.Data != head.Next.Next.Data)
            //            return false;
            //    }

            // Reverse first half of list 1/2 n
            // if n < 4, remember don't need to put list back together at the end
            // no reversing happens

            // reverse 1/2 n nodes (left half of the nodes, not including the middle node if n is odd)
            //if (nodeListLength > 1)
            //    {
            // reverse numNodesToReverse nodes at beginning of list
            // we'll undo this later to restore the list for the caller
            var numNodesToReverse = nodeListLength / 2;
            // This is true for both even and odd n

            // I like Chris' idea of actually reversing the first half
            // of the list in-place (rather than splitting it off as a
            // seperate sublist, then needing to tack it back on again)
            // Write logic to reverse k nodes each time. Then easy
            // to use the same helper for both the original reverse,
            // and the ultimate restore.

            //Console.WriteLine(head);
            //Console.WriteLine(numNodesToReverse);
            //Console.WriteLine("\n");

            // Returns head of half-reversed list
            var leftRevHead = ReverseNodesAtStartOfNodeList(head, numNodesToReverse);
            // Tail of reversed part of list is the head that was passed in
            // Tail of the reversed part of the list is still hooked up to
            // the non-reversed part of the list

            //Console.WriteLine(leftRevHead);

            var nodeAfterReversedPart = head.Next;

            //var leftRevHead = prev;

            // Handles finding proper start head for comparision (based on even or odd n)
            IntNode rightHalfHead;


            if (nodeListLength % 2 == 0)
            {
                // When n is even, start comparing at the two middlemost nodes
                rightHalfHead = nodeAfterReversedPart;
            }
            else
            {
                // When n is odd, start comparing at the nodes to the left and right of
                // the middlemost node
                rightHalfHead = nodeAfterReversedPart.Next;
            }

            // Comparisons 1/2 n
            var isPal = IntNodeListsDataAreEqual(leftRevHead, rightHalfHead);

            // Undo the reverse 1/2 n
            ReverseNodesAtStartOfNodeList(leftRevHead, numNodesToReverse);

            // Not necessary anymore:
            // Hook-up the right half of the original list
            // to the left half of the (restored) original list
            //leftRevHead.Next = nodeAfterReversedPart;

            //Console.WriteLine($"leftRevHead == {leftRevHead}");

            // Repoint what will be the restored tail now,
            // calling the restore method
            // It's the head of the (sub)list that is being resored
            // Then the reverse method just does its job normally
            // OR...do this after the helper finishes,
            // as maybe the helper nulls the Next reference on that node
            // (the undoPrev node in the helper, which is the leftRevHead outside the helper)

            //}
            return(isPal);
        }