LeetCode234 回文链表

题目

请判断一个链表是否为回文链表。

示例 1: 
输入: 1->2
输出: false 

示例 2:
输入: 1->2->2->1
输出: true

进阶: 
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 

方法

栈方法

先计算链表长度,若为偶数,将前半个链表数值存入栈,后半个链表验证与栈中数据是否一致

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
Java版本
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        int len = 0;	//获取链表长度
        ListNode node = head;
        while(node!=null){
            len++;
            node = node.next;
        }
        Stack<Integer> stack = new Stack<>();
        node = head;//把前半个链表存入栈
        for(int i=0;i<len/2;i++){
            stack.add(node.val);
            node = node.next;
        }
        if(len%2!=0){
            node = node.next; //若为奇数个,跳过中间的数
        }
        while(node!=null){
            if(node.val!=(stack.pop())){
                return false;
            }
            node = node.next;
        }
        if(stack.isEmpty()){
            return true;
        }
        return false;
    }
}
JavaScript版本
/**
 * @param {ListNode} head 
 * @return {boolean}
 */
var isPalindrome = function(head) {
    let length = 0;
    let node = head;
    while(node!==null){
        length++;
        node = node.next;
    }
    node = head;
    let stack = [];
    for(let i=0;i<parseInt(length/2);i++){
        stack.push(node);
        node = node.next;
    }
    if(length%2===1){
        node = node.next;
    }
    for(let i=0;i<parseInt(length/2);i++){
        if(node.val!==stack.pop().val) return false;
        node = node.next;
    }
    return true;
};

快慢指针法

先计算链表长度,将后半个链表反转,然后快指针从中间开始,慢指针从头开始一一对比,该方法虽然减小了空间复杂度,但需要修改原链表

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
Java版本
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        int len = 0;
        ListNode node = head;
        while(node!=null){
            len++;
            node = node.next;
        }
        node = head;
        for(int i=0;i<len/2;i++){
            node = node.next;
        }
        if(len%2!=0){
            node = node.next;
        }
        ListNode pre = null;
        ListNode next = null;
        while(node!=null){
            next = node.next;
            node.next = pre;
            pre = node;
            node = next;
        }
        node = head;
        while(pre!=null){
            if(pre.val!=node.val){
                return false;
            }
            pre = pre.next;
            node = node.next;
        }
        return true;
    }
}
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null) return true;
        ListNode slow = head,fast = head;
		//这个条件正好让slow停在第一半的最后一个节点,无论奇偶
        while(fast.next!=null&&fast.next.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode head1 = reverse(slow.next);
        slow = head;
        fast = head1;
        while(fast!=null){
            if(slow.val!=fast.val) return false;
            slow = slow.next;
            fast = fast.next;
        }
        return true;
    }
    private ListNode reverse(ListNode head){
        ListNode pre = null,node = head;
        while(node!=null){
            ListNode next = node.next;
            node.next = pre;
            pre = node;
            node = next;
        }
        return pre;
    }
}
JavaScript版本
/**
 * @param {ListNode} head 
 * @return {boolean}
 */
var isPalindrome = function(head) {
    let length = 0;
    let node = head;
    while(node!==null){
        length++;
        node = node.next;
    }
    node = head;
    for(let i=0;i<parseInt(length/2);i++){
        node = node.next;
    }
    if(length%2===1){
        node = node.next;
    }
    let pre = null;
    while(node!==null){
        let next = node.next;
        node.next = pre;
        pre = node;
        node = next;
    }
    node = head;
    while(pre!==null){
        if(pre.val!==node.val) return false;
        pre = pre.next;
        node = node.next;
    }
    return true;
};
posted @   你也要来一颗长颈鹿吗  阅读(24)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示