首页 > 其他分享 >每日一练:LeeCode-234、回文链表【链表+栈+快慢双指针】

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

时间:2024-03-26 17:59:51浏览次数:27  
标签:head slow fast next 链表 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 方法用于反转链表,采用迭代的方式实现。

标签:head,slow,fast,next,链表,LeeCode,234,节点
From: https://blog.csdn.net/kdzandlbj/article/details/137053148

相关文章

  • 【数据结构】C语言单链表的实现
    有时我们不用顺序表,而使用链表,是因为顺序表存在一定的问题1、顺序表的中间/头部的插入、删除需要挪动数据2、扩容需要申请新空间,拷贝数据,释放旧空间,存在性能的消耗3、会有空间的浪费单链表:不带头单向循环链表双链表:带头双向循环链表单链表的具体实现:1、单链表的创建:2......
  • 力扣刷题之21.合并两个有序链表
    仅做学习笔记之用。题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0]......
  • Leetcode 反转链表
    Day10刷题#######力扣官方解答:用节点作为交换方式,而非其中的值,通过增加一个空null,来使得指向完全相反。#######迭代法:classSolution{publicListNodereverseList(ListNodehead){ListNodeprev=null;ListNodecurr=head;while(cur......
  • 代码随想录第四天 链表Part02
    语言:Java参考资料:代码随想录、ChatGPT3.524.两两交换链表中的节点力扣题目链接(opensnewwindow)给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。思路这道题目正常模拟就可以了。建议......
  • 【每日算法】理论:AIGC模型 刷题:力扣链表操作
    上期文章【每日算法】理论:图像分割相关刷题:设计链表文章目录上期文章一、上期问题二、理论问题1、LAMAInpaint2、IPadapter模型3、Anydoor4、vit(VisionTransformer)架构5、MAE6、CLIP模型三、力扣刷题回顾-链表操作203.移除链表元素206.反转链表24.两两交换链表......
  • 实现双向链表
    1classNode{2intdata;3Nodenext;4Node(intdata){5this.data=data;6}7}8publicclassMyNodes{9privateNodehead;10privateNodelast;11privateintsize;12publicNodeget(intindex){13......
  • 速通数据结构第三站 单链表
    系列文章目录速通数据结构与算法系列1  速通数据结构与算法第一站复杂度          http://t.csdnimg.cn/sxEGF2  速通数据结构与算法第二站顺序表 3 速通数据结构与算法第二站单链表 感谢佬们支持!目录系列文章目录前言一、单链表   ......
  • L2-022 重排链表(25分) c++代码
    给定一个单链表 L1​→L2​→⋯→Ln−1​→Ln​,请编写程序将链表重新排列为 Ln​→L1​→Ln−1​→L2​→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。输入格式:每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (......
  • 每日一练:LeeCode-38、外观数列【字符串】
    给定一个正整数n,输出外观数列的第n项。「外观数列」是一个整数序列,从数字1开始,序列中的每一项都是对前一项的描述。你可以将其视作是由递归公式定义的数字字符串序列:countAndSay(1)="1"countAndSay(n)是对countAndSay(n-1)的描述,然后转换成另一个数字字符串。......
  • 单链表删除相同的元素
    #include<iostream>#include<stdlib.h>usingnamespacestd;#defineerror-1#defineok1typedefintStatus;typedefintElemType;typedefstructLNode{ ElemTypedata; LNode*next;}LNode,*LinkList;StatusCreateList(LinkList&L,int......