大家好!我是曾续缘❣️
今天是《LeetCode 热题 100》系列
发车第 24 天
链表第 3 题
❤️点赞 👍 收藏 ⭐再看,养成习惯
回文链表 给你一个单链表的头节点
head
,请你判断该链表是否为回文链表。如果是,返回true
;否则,返回false
。示例 1:
输入:head = [1,2,2,1] 输出:true示例 2:
输入:head = [1,2] 输出:false提示:
- 链表中节点数目在范围
[1, 105]
内0 <= Node.val <= 9
进阶:你能否用
难度:❤️O(n)
时间复杂度和O(1)
空间复杂度解决此题?
解题方法
使用递归遍历链表时,我们可以做到从后往前读取链表的值,这在递归结束后自动移动。
使用全局变量fornt
,我们可以做到从前往后读取链表的值,这需要在递归结束后手动移动。
递归结束后,是返回前一个结点的,为了使front
往后读取,使其对应回文结点,需要在递归返回时将全局变量fornt
往后读取。
- 使用递归和双指针的方法来判断链表是否为回文链表。
- 设计一个递归函数
recurse(ListNode cur)
,该函数用于从链表头部向尾部递归,并在递归返回时从链表尾部向头部比较节点的值是否相等。 - 在递归函数中,先递归到链表尾部,然后从尾部向头部比较节点值,如果存在不相等的情况则返回 false,否则返回 true。
- 在主函数
isPalindrome(ListNode head)
中,设置一个全局变量front
作为参考节点,通过递归函数recurse
来判断链表是否为回文链表。
时间复杂度:O(n),其中 n 表示链表的长度,需要遍历整个链表来进行比较。
空间复杂度:O(n),递归调用栈的深度取决于链表的长度。
Code
/**
* 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 {
private ListNode front;
private boolean recurse(ListNode cur){
if(cur == null){
return true;
}
if(!recurse(cur.next)){
return false;
}
if(cur.val != front.val){
return false;
}
front = front.next;
return true;
}
public boolean isPalindrome(ListNode head) {
front = head;
return recurse(head);
}
}