①中文题目

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

②思路

   首先,找到链表的中间结点在哪,用j标记,此处用到leetcode的876题,也就是我上一篇博文里那个题。从而把链表分为前半截和后半截。

  然后,把后半截链表反转一下,记为x,如果x和前半截链表长得一模一样,那就返回true,不一样就返回false。

③代码

 1 class Solution {
 2     public boolean isPalindrome(ListNode head) {
 3         ListNode temp1=head;
 4         ListNode temp2=head;
 5         int i=1;
 6         int k=0;
 7         boolean flag=false;
 8         while(head==null||head.next==null)
 9             return true;    //链表长度为0或者1,要单独拿出来说
10
11
12         while(temp1.next!=null){
13             i+=1;
14             temp1=temp1.next;
15         }
16         for(int j=0;j<i/2;j++){           //i就是链表的一半处
17             temp2=temp2.next;   //找到中间结点
18         }                           //至此,temp2就是后半截链表的头结点
19         ListNode pre=null;
20         ListNode curr;           //curr是后半截链表的起点。
21         if(i%2==0)             //根据链表长度为奇数还是偶数,来决定后半截链表的起点。
22             curr=temp2;
23         else
24             curr=temp2.next;
25         ListNode buf=null;           //buff就是个缓存而已,有点像206题里的temp
26         while(curr!=null){
27             buf=curr.next;
28             curr.next=pre;
29             pre=curr;
30             curr=buf;             //整个反转过程,时间复杂度是O(N),空间复杂度是O(1)
31         }                      //至此,后半截链表已经被反转    //head保存的是前半截链表的头结点,pre是后半截链表反转之后的头结点
32         while(pre!=null){            //不能用head.next!=null去判断,因为前半截的最后一个结点的后边不是null。
33             if(head.val==pre.val){
34                 head=head.next;
35                 pre=pre.next;
36                 k+=1;
37             }
38             else{
39                 return false;   //一旦发现元素不等的现象,立刻返回false
40             }
41         }
42         if(k==i/2)
43             flag=true;        //用k来作为flag翻不翻转的标志
44     return flag;
45
46     }
47 }

④运行结果

执行结果:通过
显示详情
执行用时 :1 ms, 在所有 Java 提交中击败了99.89%的用户
内存消耗 :40.4 MB, 在所有 Java 提交中击败了97.88%的用户

⑤学到的东西 

   1、回文链表是什么?

          上海自来水来自海上

          黄山落叶松叶落山黄。这个例子摘自网上别人的回答。

   2、回文链表里,如果链表长度为0,1个,都要单独拿出来讨论。

   3、链表长度为奇数和偶数时,后半截链表的起点是不一样的。

           比如链表长度为5,比如[1,2,3,2,1],那么如果后半截链表起点应该是[3,2,1]中的2,而不是3。

           比如链表长度为6,比如[1,2,3,3,2,1],那么如果后半截链表起点应该是[3,2,1]中的3。

    4、本题就是206题和876题的结合,我把两个程序并在一起写的。我看到网上有的人是把两个程序写在两个函数里的,再进行调用的。

               比如把206题程序装在reverseListNode函数里,把876题装在getMidListNode函数里,再在主程序里调用(不是main函数,就是普通函数之间的调用)。

01-23 17:51
查看更多