携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
一、题目描述:
234. 回文链表 - 力扣(LeetCode) (leetcode-cn.com)
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
提示:
- 链表中节点数目在范围[1, 10^5] 内
- 0 <= Node.val <= 9
进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
二、思路分析:
这个题目看起来很简单,我最开始思路是利用之前做过的反转链表的代码,然后比较两个链表是否每个的节点的值都一致,结果不对!!!
哈哈哈哈,错误在于这是链表,我通过反转链表操作已经把原来链表的连接方式完全改变了!原先的链表不存在了!!!所以直接反转整个链表不行
三种方法 其中递归法,我的比较好懂,但是时间复杂度太高,可是官方题解有点难看懂,就先不看了 第三种是 利用快慢指针来反转后半部分链表,这样的好处是可以不消耗额外的内存,因此空间复杂度是O(0)
三、AC 代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private ListNode reverseList(ListNode head) {//反转链表
ListNode curr=head,prev=null,temp=null;
while(curr!=null){
temp=curr.next;
curr.next=prev;
prev=curr;
curr=temp;
}
return prev;
}
public boolean isPalindrome(ListNode head) {
ListNode dummy=new ListNode(-1);
dummy.next=head;//加一个伪头结点,,不然俩指针都从第一个开始的话,在偶数个节点的时候,慢指针就走超了
ListNode fast=dummy,slow=dummy;//快慢指针
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode newhead=null;
if(fast==null) newhead=reverseList(slow);//奇数个节点,慢指针刚好在中心处,得到后半段的反转链表
else{
newhead=reverseList(slow.next);
slow.next=null;//与上一种情况不同,要把slow封口
}
while(head!=null){
if(head.val!=newhead.val) return false;
head=head.next;
newhead=newhead.next;
}
return true;
}
}