Java-链表的回文结构【牛客网】

题目描述

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:

1->2->2->1

返回:true

解题思路:
不符合规范的两种思路(空间复杂度为O(N)):

1、如果是一个字符串/数组判定回文非常简单:用一个left下标从0开始,用一个right下标从最后一个位置开始;依次比较,如果left位置的元素和right位置的元素不相等,就不是回文,如果所有都相等,就是回文。

2、单向链表(只能从前往后,不能从后往前)
链表逆置:先把这个链表A复制一份得到链表B,再把这个链表B逆置一下,从A和B的开头依次往后遍历比较。

符合规范的思路(空间复杂度为O(1)):
3、先找到这个链表的中间结点(可能是奇数个节点,也可能是偶数个节点),从中间结点位置开始,对后半个链表进行逆置操作,从两个(半个)链表的开头依次遍历,进行比较即可。

在这里插入图片描述

代码实现:

public class PalindromeList {
    
    
     public boolean chkPalindrome(ListNode A) {
    
    
   //1、先找到A链表的中间结点。
   int size=size(A);
   int steps=size/2;
   ListNode B=A;
   for(int i=0;i<steps;i++) {
    
    
    B=B.next;
   }
   //2、从B开始对后面的链表进行逆置操作
   ListNode prev=null;
   ListNode cur=B;
   while(cur!=null) {
    
    
    ListNode next=cur.next;
    if(next==null) {
    
    
     //说明此时的cur已经是链表最后一个节点了,更新头节点的位置。
     B=cur;
    }
    cur.next=prev;
    prev=cur;
    cur=next;
   }
   //3、分别从A和B出发,来依次对两个链表的元素判断是否对应相等
   //如果链表长度为奇数,A和B的长度相同,无影响
   //如果链表长度为偶数,A会比B长一个元素,此时要注意遍历链表的时候循环结束条件要以B为基准
   while(B!=null) {
    
    
    if(A.val!=B.val) {
    
    
     //对应元素不同,说明不是回文结构
     return false;
    }
    A=A.next;
    B=B.next;
   }
   return true;
  }
  public int size(ListNode head) {
    
    
    int size=0;
    ListNode cur=head;
    while(cur!=null) {
    
    
     size++;
     cur=cur.next;
    }
    return size;
   }
}

猜你喜欢

转载自blog.csdn.net/weixin_44378053/article/details/105629396