难度:简单–看起来比较像中等
频次:52
题目:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
解题思路:链表分成两个链表,后面链表反转。最后比较
注意:
- 通过中间节点分两个链表,如果是奇数,中间节点要放前面。偶数,中间节点放前面(所以不能要虚拟节点,虚拟节点偶数的中间节点是相同里面的后一个)
- 对比的时候,如果遇到不相同的就返回false,如果能够跳出循环,最后直接返回true
- 条件 必须是短的做判断,如果是长的,就会有一个跟null做对比
代码:
/**
* 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 temp=head;
ListNode newhead=head;
temp=middleNode(head);
if(temp.next==null) return true;
newhead=temp.next;
//后面部分反转链表
newhead=reversal(newhead);
//对比
while(newhead!=null){
if(head.val!=newhead.val) return false;
head=head.next;
newhead=newhead.next;
}
return true;
}
//奇数,要求中间节点作为第一个链表的,即中间节点要作为前面的链表-->偶数也就是要返回前一个节点
public ListNode middleNode(ListNode head){
ListNode fast=head,slow=head;
while(fast.next!=null&&fast.next.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
//反转链表
public ListNode reversal(ListNode head){
ListNode dummyhead=new ListNode(-1);
dummyhead.next=head;
ListNode g=dummyhead,p=head;
while(p.next!=null){
ListNode temp=p.next;
p.next=temp.next;
temp.next=g.next;
g.next=temp;
}
return dummyhead.next;
}
}