32.回文链表

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

解析:
1.利用栈求解

①首先遍历链表获取链表的长度len;
②根据链表的长度,将链表的前半部分压入栈,将后半部分依次与弹栈的元素比较看是否一致,一致则为回文链表;
③这里注意的是链表的后半部分的开始位置(链表长度的奇偶)。

public boolean isPalindrome1(ListNode head) {
   if (head == null) return true;
   if (head.next == null) return true;//链表只有一个的时候
   int len = 0;
   ListNode first = head;
   //链表的长度
   while (head != null){
    head = head.next;
    len++;
   }
  //前半部分压入栈
   Stack<Integer> stack = new Stack<Integer>();
   int mid = len/2;
   if (len%2 == 0){
    while ((mid--)!=0){
     stack.push(first.val);
     first = first.next;
    }
    //注意区分mid--和--mid时遍历停止时的first指向的结点
    //链表长度是偶数,此时first表示链表后半部分的开始
   }else{
    while ((mid--)!=0){
     stack.push(first.val);
     first = first.next;
    }
    first = first.next;
   //链表长度是奇数,此时first表示链表后半部分的开始
   }
   //后半部分与栈中元素比较
   while (first!=null){
    if (first.val != stack.pop())
     return false;
    first = first.next;
   }
   return true;
  }

2.双指针—链表反转
①定义两个指针p1和p2,开始同时指向头结点;
②指针p1和p2同时移动,p1移动一个节点,p2移动两个结点,当p2移动到链表的末尾无法在移动时,此时p1刚好指向链表的中间结点;
例:
1->2->2->1 p1停留在第一个结点2上
1->2->3->2->1 p1停留在结点3上
③进行反转p1后面的部分链表操作;
④比较前半部分的链表和反转的后半部分链表。(从上述例中明显可以看出,不区分链表的奇偶)

public boolean isPalindrome2(ListNode head) {
   if (head == null) return true;
   if (head.next == null) return true;
   ListNode p1 = head, p2 = head;
   
   //利用快慢指针,将p1移动到链表的中间部分
   while (p2.next != null && p2.next.next != null){
    p1 = p1.next;
    p2 = p2.next.next;
   }
   //反转此时p1之后的链表
   //不用考虑链表的奇偶
   ListNode pre = null, curnode = null, tmpnode = p1.next;
   while (tmpnode != null){
    curnode = tmpnode.next;
    tmpnode.next = pre;
    pre = tmpnode;
    tmpnode = curnode;
   }
   p1.next = pre;//接上反转后的链表
   //比较前半部分和反转后的部分是否一致
   while(pre != null){
    if (head.val != pre.val)
     return false;
    head = head.next;
    pre = pre.next;
   }
   return true;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值