这是我参与更文挑战的第10天,活动详情查看: 更文挑战
234. 回文链表
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
友情链接
思路解析
因为是链表,只能一个一个移动着遍历,先用 O(n) 的时间遍历完链表,把每一个节点存储下来。因为是要前一个后一个,前一个后一个,前一个后一个这样对比,正好利用栈的数据结构后进先出的特性来存储,所以空间复杂度也为 O(n) 。
每次循环都取出栈的最上面那个元素,和链表顺序比对。一旦不相同,就意味着这个链表不是回文链表。直至比较到栈为空的时候。
算法实现
/**
* 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) {
LinkedList<Integer> stack=new LinkedList<>();
ListNode item=head;
while(item!=null){
stack.push(item.val);
item=item.next;
}
while(!stack.isEmpty()){
if(stack.pop()==head.val){
head=head.next;
}else{
return false;
}
}
return true;
}
}
进阶设计
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
用 O(n) 时间复杂度和 O(1) 空间复杂度的进阶实现方式,可以借助递归算法来实现。
比如说这个链表: 1->2->3->4->5->4->3->2->1
定义一个 ListNode 的变量 ref 指向第一个元素。定义直至到达最后一个元素时开始调用递归循环过程。在每一次递归调用过程中,都去判断当前元素的值是否等于 ref 所指向元素的值。如果相同,更新 ref 指向下一个元素,继续递归调用。如果不相同,直接返回结果 false 即可代表该链表不是回文链表。
Java 版本的代码实现如下所示。
/**
* 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 {
ListNode ref;
public boolean isPalindrome(ListNode head) {
ref=head;
return recursive(head);
}
public boolean recursive(ListNode head) {
if(head==null)return true;
boolean ans=recursive(head.next);
boolean isEqual = (head.val==ref.val)?true:false;
ref=ref.next;
return ans&isEqual;
}
}