回文链接列表问题-算法

时间:2019-06-25 01:26:57

标签: algorithm

 class PalindromicLinkedList {

   public static boolean isPalindrome(ListNode head) {
     if (head == null || head.next == null)
       return true;

     // find middle of the LinkedList
     ListNode slow = head;
     ListNode fast = head;
     while (fast != null && fast.next != null) {
       slow = slow.next;
       fast = fast.next.next;
     }

     ListNode headSecondHalf = reverse(slow); // reverse the second half
     ListNode copyHeadSecondHalf = headSecondHalf; // store the head of reversed part to revert back later

     ListNode start = head;
     // compare the first and the second half
     while (start != null && headSecondHalf != null) {
       if (start.value != headSecondHalf.value) {
         return false; // not a palindrome
       }
       start = start.next;
       headSecondHalf = headSecondHalf.next;
     }

     reverse(copyHeadSecondHalf); // revert the reverse of the second half

    return true;
   }

   private static ListNode reverse(ListNode head) {
     ListNode prev = null;
     while (head != null) {
       ListNode next = head.next;
       head.next = prev;
       prev = head;
       head = next;
     }
     return prev;
   }
   }
 }

这是回文链接列表问题

  

给出单个LinkedList的头部,编写一种方法来检查   LinkedList是否是回文。

     

您的算法应使用恒定空间,算法完成后,输入LinkedList的格式应为原始形式。该算法应具有O(N)O(N)的时间复杂度,其中“ N”是LinkedList中的节点数。

以上代码是解决此问题的方法, 而且我了解其中的大部分内容,但很难理解

  

reverse(copyHeadSecondHalf);

我可能只是猜测这是针对算法条件的

  

算法完成后,输入LinkedList应该采用原始形式。

但是上面的代码, 我们是否曾经更改或修改过输入LinkedList? 每次我们定义新的ListNode指向头参考时 或其他一些。

同样,我们只有新变量“ headSecondHalf”具有新的反向版本LinkedList。 甚至我们在copyHeadSecondHalf上什么也没做。

  

但是我们为什么要拥有

 reverse(copyHeadSecondHalf);

2 个答案:

答案 0 :(得分:2)

  

但是上面的代码,我们是否曾经更改或修改过输入LinkedList?每次我们定义新的ListNode指向头参考或其他参考时。

是的,原始的LinkedList被修改了。

 ListNode headSecondHalf = reverse(slow); // reverse the second half

以上行以LinkedList的中间作为输入并将其反转。结果,LinkedList的结构被更改。

例如:5→2→3→2 *→5 *

慢速指针位于位置3。
现在,headSecondHalf指向5 *→2 *→3

由于反向操作,3指向NULL,因此原始列表变为5→2→3(仅列表的一半)。


  

同样,我们只有新变量“ headSecondHalf”具有新的反向版本LinkedList。甚至我们在copyHeadSecondHalf上什么也没做。

headSecondHalf变量用于检查列表是否为回文。这意味着位置已更改。因此,该值将被复制到copyHeadSecondHalf,然后再次反转该值,以便恢复原始列表。

答案 1 :(得分:0)

考虑以下链接列表示例

1->2->3->4->2'->1'->NULL

在第一个相反的情况下,我们得到一个新的链表,如下所示:

1'->2'->4->NULL

原始链接列表如下

1->2->3->4->NULL

比较之后,我们需要根据条件之一恢复链接列表。因此是相反的步骤。

但是,在代码中,虽然返回false,但没有执行最后一步,这违反了该规则。因此,您可以在返回前添加反向,或中断while循环,反向并在最后返回