java 回文序列,leetcode刷题笔记-234. 回文链表(java实现)

leetcode刷题笔记-234. 回文链表(java实现)

题目描述

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

示例 1:输入: 1->2

输出: false

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

输出: true

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/palindrome-linked-list

解题思路

寻找回文串的核心思想是从中心向两端扩展。

因为回文串可能是基数也可能是偶数,长度为奇数时只存在一个中心点,长度为偶数时存在两个中心点。

判断是否为回文串的思路比较简单,不需要考虑奇偶情况,从两端向中心逼近即可。

(因为回文串是对称的,所以正着读和倒着读应该是一样的,这一特点是解决回文串问题的关键)

判断单链表是否为回文链表:

关键单链表无法倒着遍历,无法使用双指针技巧。最简单的办法是把链表反转存入新的链表,比较两者是否一致。

其实,借助二叉树后序遍历的思路,不需要显示反转链表也可以倒叙遍历链表。

链表其实也是可以有前序和后序遍历的

实际上就是把链表节点放入一个栈,然后再拿出来,这时候元素的顺序是反的。

还有更好的思路:

先通过双指针的快慢指针找到链表的中点;ListNode slow, fast;

slow = fast = head;

while (fast != null && fast.next != null) {

slow = slow.next;

fast = fast.next.next;

}

// slow 指针现在指向链表中点

如果fast没指向null说明链表长度为奇数(slow还要再往前一步),否则为偶数;if (fast != null)

slow = slow.next;

从slow开始反转后边的链表就可以开始比较回文了。

该方法总体时间复杂度为O(n),空间复杂度为O(1)

参考来源:https://labuladong.gitbook.io/algo/shu-ju-jie-gou-xi-lie/shou-ba-shou-shua-lian-biao-ti-mu-xun-lian-di-gui-si-wei/pan-duan-hui-wen-lian-biao

解题代码

方法一://链表后序遍历方法,通过递归方式反转链表

/**

* Definition for singly-linked list.

* public class ListNode {

*     int val;

*     ListNode next;

*     ListNode() {}

*     ListNode(int val) { this.val = val; }

*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }

* }

*/

class Solution {

public ListNode l;

public boolean isPalindrome(ListNode head) {

l = head;

return compVal(head);

}

private boolean compVal(ListNode r) {

if(r == null) {

return true;

}

boolean result = compVal(r.next);

if(result && (r.val == l.val)) {

l = l.next;

return true;

}

return false;

}

}

方法二:更好的思路//通过快慢指针方式

/**

* Definition for singly-linked list.

* public class ListNode {

*     int val;

*     ListNode next;

*     ListNode() {}

*     ListNode(int val) { this.val = val; }

*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }

* }

*/

class Solution {

public boolean isPalindrome(ListNode head) {

//快慢指针找到链表中点

ListNode s = head, f = head;

while(f != null && f.next != null) {

s = s.next;

f = f.next.next;

}

if(f != null) {

s = s.next;

}

//反转后半段链表

ListNode p=head, q=reverse(s);

//比较两段链表

while(q!=null) {

if(p.val != q.val) {

return false;

}

p = p.next;

q = q.next;

}

return true;

}

public ListNode reverse(ListNode h) {

ListNode p = null, c = h;

while(c != null) {

ListNode n = c.next;

c.next = p;

p = c;

c = n;

}

return p;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值