题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
方法一
上来做这道题,最先想到的方法就是建一个列表,遍历一遍链表,将每一个值存入列表,然后再对列表进行循环判断是否回文。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null) return true;
List<Integer> list = new ArrayList<Integer>();
while(head!=null){
list.add(head.val);
head = head.next;
}
int count=list.size()-1;
for(int i=0;i<list.size();i++){
//此处不能用==判断相等
if(!list.get(i).equals(list.get(count))){
return false;
}
count--;
}
return true;
}
}
在算法中有一个需要注意的点,不能用==判断相等,必须用equals否则报错。如在输入为[128,128]时报错。查了查资料,才知道是因为:JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围,所以当为Integer i=127时,在自动装箱过程中是取自常量池中的数值,而当Integer i=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。
用时:5ms,内存:43.6MB。
方法二
看了一些其他解法,有了下边的代码
class Solution {
public boolean isPalindrome(ListNode head) {
//solution2
if(head==null || head.next ==null) return true;
ListNode fast = head;
ListNode slow = head;
ListNode pre = null;
//快慢指针,找到链表的中点
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
//将slow之后的链表反转
while(slow!=null){
ListNode next = slow.next;
slow.next = pre;
pre = slow;
slow = next;
}
//前后链表进行比较,若为奇数链表,多一个节点,也不影响判断回文
while(head!=null && pre!=null){
if(head.val!=pre.val) return false;
head = head.next;
pre = pre.next;
}
return true;
}
}
用时:1ms,内存:42.5MB。