每日一练:LeeCode-234、回文链表【链表+栈+快慢双指针】

给你一个单链表的头节点 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) 空间复杂度解决此题?

方法1:使用栈解决

思路使用栈先把链表的节点全部存放到栈中,然后再一个个出栈,这样就相当于链表从后往前访问了

其实我们只需要拿链表的后半部分和前半部分比较即可没必要全部比较,所以这里可以优化一下

class Solution {
    public boolean isPalindrome(ListNode head) {
        Stack<Integer> stack = new Stack<>(); // 创建一个整数类型的栈,用于存储单链表中的节点值
        ListNode temp = head; // 创建一个临时节点 temp,指向链表的头节点 head,用于遍历链表
        int len = 0; // 初始化变量 len,用于记录链表的长度

        // 遍历链表,将链表中的节点值依次压入栈中,并记录链表的长度
        while (temp != null) {
            stack.push(temp.val); // 将当前节点的值压入栈中
            temp = temp.next; // 将指针移动到下一个节点
            len++; // 长度加一
        }

        len >>= 1; // 计算链表的长度的一半。由于接下来是将栈中的值与链表的前半部分比较,因此只需要比较一半即可

        // 循环比较链表前半部分与栈中的值
        while (len-- >= 0) {
            if (head.val != stack.pop()) // 如果链表前半部分的值与栈中弹出的值不相等,返回 false
                return false;
            head = head.next; // 将链表的指针指向下一个节点,继续比较
        }
        return true; // 如果循环结束,说明链表是回文的,返回 true
    }
}

方法3:反转后半部分链表(牛逼)

思路通过找到链表的中间节点然后把链表后半部分反转,最后再用后半部分反转的链表和前半部分一个个比较即可
这段代码实现了判断给定的单链表是否是回文的功能。下面是对代码的详细解释:

public boolean isPalindrome(ListNode head) {
    ListNode fast = head, slow = head;
    // 通过快慢指针找到链表的中点
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    // 如果 fast 不为空,说明链表的长度是奇数个,需要跳过中间节点
    if (fast != null) {
        slow = slow.next;
    }
    // 反转后半部分链表
    slow = reverse(slow);

    fast = head;
    // 比较前半部分和后半部分的链表是否相等
    while (slow != null) {
        if (fast.val != slow.val)
            return false;
        fast = fast.next;
        slow = slow.next;
    }
    return true;
}

// 反转链表
public ListNode reverse(ListNode head) {
    ListNode prev = null;
    while (head != null) {
        ListNode next = head.next;
        head.next = prev;
        prev = head;
        head = next;
    }
    return prev;
}
  • isPalindrome 方法中,使用快慢指针找到链表的中点。如果链表长度是奇数,快指针 fast 会多走一步,此时 slow 指向的是中间节点的下一个节点。
  • 然后将后半部分链表反转,并将反转后的头节点赋值给 slow
  • 最后,通过比较前半部分链表和反转后的后半部分链表的节点值是否相等,来判断链表是否是回文的。
  • reverse 方法用于反转链表,采用迭代的方式实现。

相关推荐

  1. leetcode 234

    2024-03-26 22:10:02       48 阅读
  2. leetcode100-024】【/快慢指针

    2024-03-26 22:10:02       56 阅读
  3. 234.

    2024-03-26 22:10:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-26 22:10:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-26 22:10:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-26 22:10:02       82 阅读
  4. Python语言-面向对象

    2024-03-26 22:10:02       91 阅读

热门阅读

  1. ARM IHI0069F GIC architecture specification (2)

    2024-03-26 22:10:02       32 阅读
  2. day8 ARM

    day8 ARM

    2024-03-26 22:10:02      39 阅读
  3. vue js金额转中文

    2024-03-26 22:10:02       43 阅读
  4. 逻辑回归的详解及应用

    2024-03-26 22:10:02       37 阅读
  5. 第二十七章 TypeScript TS进阶用法infer

    2024-03-26 22:10:02       35 阅读
  6. ubuntu 搭建 sonic v2.6.4 平台记录

    2024-03-26 22:10:02       33 阅读
  7. 【C++】6-2 交换函数2 分数 10

    2024-03-26 22:10:02       34 阅读
  8. ChatGPT秘籍:让ChatGPT帮你打造出色论文

    2024-03-26 22:10:02       39 阅读
  9. 解释器模式

    2024-03-26 22:10:02       35 阅读
  10. iptables笔记

    2024-03-26 22:10:02       34 阅读
  11. Vue中如何实现动态改变字体大小

    2024-03-26 22:10:02       42 阅读