234. 回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例:
输入:head = [1,2,2,1]
输出:true
第一种方法:
快慢指针+反转链表+奇偶判断
/**
* 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 cur=head;//这是反转的中间指针
ListNode prev=null;//空指针
ListNode temp;//这是为了遍历用的指针
ListNode slow=head;//快慢指针
ListNode fast=head;
boolean flag=true;//标志位
if(head!=null && head.next==null){return true;}//这是边界考虑单个元素的情况,直接返回true
while(fast!=null && fast.next!=null)//快慢指针找寻中间点
{
fast=fast.next.next;
slow=slow.next;
}
if(fast!=null){slow=slow.next;}//当快指针不为null,证明为奇数,所以slow后移一位
while(cur!=slow)//只要不等于slow就反转
{
temp=cur.next;
cur.next=prev;
prev=cur;
cur=temp;
}
if(fast!=null){prev=prev.next;}//奇数情况,中间值不用判断,直接prev后移一位
while(slow!=null && prev!=null)//判断两种不为null的时候运行比较数值,防止空指针异常
{
if(slow.val!=prev.val)
{
flag=false;
break;
}
slow=slow.next;
prev=prev.next;
}
return flag;
}
}
第二种方法:
数组法,这里就说下思路,就是定义一个ArrayList数组,然后将一个指针指向头结点,然后结点挨个存储在这个ArrayList数组,然后在用左右边界依次比较判断是否回文,这种是比较简单的方案了。
/**
* 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 cur=head;
boolean flag=true;
List<ListNode> list=new ArrayList<>();//把结点挨着保存起来
while(cur!=null)
{
list.add(cur);
cur=cur.next;
}
int left=0,right=list.size()-1;
while(left<right)
{
if(list.get(left).val!=list.get(right).val)
{
return false;
}
left++;
right--;
}
return flag;
}
}
代码的性能相对于上一个就低得多了,建议还是采用第一种方案。