LeetCode 算法:回文链表 c++

news2025/1/13 10:20:09

原题链接🔗:回文链表
难度:简单⭐️

题目

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

题解

解决"回文链表"问题,我们可以采用以下几种解题思路:

1. 双指针法(快慢指针)

  • 目的:找到链表的中点。
  • 方法:使用两个指针,一个快指针(每次移动两个节点),一个慢指针(每次移动一个节点)。当快指针到达链表末尾时,慢指针即为中点。

2. 反转链表的后半部分

  • 目的:将链表的后半部分反转,以便可以直接比较。
  • 方法:从找到的中点开始,反转链表的后半部分。

3. 比较前半部分和反转后的后半部分

  • 目的:判断链表是否是回文。
  • 方法:使用两个指针,一个从链表头部开始,另一个从反转后的后半部分开始,逐个比较节点的值。

4. 恢复链表

  • 目的:在判断完是否是回文后,恢复链表的原始结构。
  • 方法:将反转的后半部分再次反转,以恢复链表的原始顺序。

5. 递归方法

  • 目的:递归地比较链表的首尾元素,然后对剩余部分递归进行判断。
  • 方法:定义一个递归函数,比较当前头节点和尾节点的值,如果相等,对子链表进行递归调用。

详细步骤

  1. 初始化两个指针slowfast,都指向头节点。
  2. 移动指针fast 每次移动两个节点,slow 每次移动一个节点,直到 fast 到达链表末尾或其下一个节点。
  3. 反转链表的后半部分:从 slow 节点开始,反转链表的后半部分。
  4. 比较链表的前半部分和反转后的后半部分:使用两个指针,一个从链表头部开始,另一个从反转后的后半部分开始,逐个比较节点的值。
  5. 判断是否是回文:如果所有值都匹配,则链表是回文的;如果有不匹配的值,则链表不是回文的。
  6. 恢复链表:如果需要,将反转的后半部分再次反转,以恢复链表的原始顺序。

注意事项

  • 在反转链表时,需要小心处理边界情况,如链表为空或只有一个节点。
  • 在比较过程中,确保比较的是相同位置的节点。
  • 如果使用递归方法,注意递归的终止条件和防止栈溢出。

通过上述步骤,你可以清晰地理解如何判断一个链表是否是回文,并选择适合的方法来实现算法。

快慢指针法

  1. 复杂度:时间复杂度O(n),空间复杂度O(1)。
  2. 过程
  • ListNode结构体:定义了链表的节点,包含整数值val和指向下一个节点的指针next。
  • Solution类:包含isPalindrome方法,用于判断链表是否是回文。
  • 快慢指针:在isPalindrome方法中,使用快慢指针找到链表的中点。
  • 反转链表:使用reverse辅助函数反转链表的后半部分。
  • 比较:使用两个指针比较链表的前半部分和反转后的后半部分。
  • 恢复链表:在比较完成后,再次调用reverse函数恢复链表的后半部分,以保持原始链表结构。
  • main函数:创建示例链表,调用isPalindrome方法,并输出结果。然后释放链表占用的内存。
  1. c++ demo
#include <iostream>

// 定义链表节点
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    // 判断链表是否是回文
    bool isPalindrome(ListNode* head) {
        if (!head || !head->next) return true; // 空链表或只有一个节点是回文

        // 使用快慢指针找到链表中点
        ListNode* slow = head, * fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }

        // 反转链表的后半部分
        ListNode* secondHalf = reverse(slow);

        // 判断前半部分和反转后的后半部分是否相等
        ListNode* p1 = head, * p2 = secondHalf;
        bool isPalin = true;
        while (p2) {
            if (p1->val != p2->val) {
                isPalin = false;
                break;
            }
            p1 = p1->next;
            p2 = p2->next;
        }

        // 恢复链表的后半部分
        reverse(secondHalf);

        return isPalin;
    }

private:
    // 反转链表的辅助函数
    ListNode* reverse(ListNode* head) {
        ListNode* prev = nullptr, * curr = head, * next = nullptr;
        while (curr) {
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
};

// 主函数,用于演示
int main() {
    Solution solution;

    // 创建一个示例链表: 1 -> 2 -> 2 -> 1
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(2);
    head->next->next->next = new ListNode(1);

    // 判断链表是否是回文
    bool isPalin = solution.isPalindrome(head);
    std::cout << (isPalin ? "链表是回文" : "链表不是回文") << std::endl;

    // 释放链表内存
    ListNode* current = head;
    while (current) {
        ListNode* next = current->next;
        delete current;
        current = next;
    }

    return 0;
}
  • 输出结果:

链表是回文
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1827729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用 Google Chrome 浏览器浏览经过 XSLT 渲染的 XML 文件

对于经过XSLT渲染的XML文件&#xff0c;本来&#xff0c;可以直接用 IE (Internet Explorer) 打开&#xff0c;就能看到渲染之后的样子&#xff0c;很方便。但是后来&#xff0c;微软把 IE 换成了 Microsoft Edge&#xff0c;按理说这是比 IE 更先进的浏览器&#xff0c;可是偏…

Swift 是 C++ 的最佳继任者

苹果称 Swift 是 C 的最佳继任者 Swift 是苹果公司在 2014 年推出的&#xff0c;一款旨在替代 Objective-C 的编程语言。但苹果语言和运行时总监 Ted Kremenek 在 WWDC24 的主题演讲中表示&#xff0c;Swift 也将取代 C。 “Swift 的安全性、速度和易用性&#xff0c;加上内…

期末复习6--链表头插法(逆序)尾插法(顺序)---输出链表

头插法 #include <stdio.h> #include <stdlib.h>struct Node //定义结构体 {char data; //数据域struct Node * next; //指针域 };/* 请在这里填写答案 */void PrintList (struct Node * head) {struct Node * s;if(head NULL){printf("None&qu…

Python基础教程(二十一):多线程

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

在ubuntu中启动docker的mysql8镜像

首先查看docker是否启动&#xff1a; docker ps #出现信息就是启动成功 启动命令&#xff1a; sudo systemctl start docker 设置开机自启&#xff1a; sudo systemctl enable docker 查询下载好的mysql8的镜像文件&#xff1a; docker images 在启动查询好的镜像文件&#…

StarNet实战:使用StarNet实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 https://arxiv.org/pdf/2403.19967 论文主要集中在介绍和分析一种新兴的学习范式——星操作&#xff08;Star Operation&#xff09;&#xff0c;这是一种通过元素级乘法融合不同子…

521. 最长特殊序列 Ⅰ(Rust单百解法-脑筋急转弯)

题目 给你两个字符串 a 和 b&#xff0c;请返回 这两个字符串中 最长的特殊序列 的长度。如果不存在&#xff0c;则返回 -1 。 「最长特殊序列」 定义如下&#xff1a;该序列为 某字符串独有的最长 子序列 &#xff08;即不能是其他字符串的子序列&#xff09; 。 字符串 s …

从传统到智能:数字孪生在火电厂中的应用

通过图扑 HT 可视化技术数字孪生正在运行的火力发电厂&#xff0c;搭建数字化运营平台&#xff0c;对发电厂进行工厂式精细化的数字化管理&#xff0c;提升企业对整个发电厂业务进行数字化管理能力。

安装wsl

安装wsl 先决条件&#xff1a; 打开控制面板->选择程序与功能->选择启动或关闭windows功能&#xff0c;将以下框选的勾选上 二、到Mircosoft store下载Ubuntu 三、如果以上都勾选了还报以下错误 注册表错误 0x8007019e Error code: Wsl/CallMsi/REGDB_E_CLASSNOTREG…

gma 2.0.10 (2024.06.16) | GmaGIS V0.0.0a4 更新日志

安装 gma 2.0.10 pip install gma2.0.10网盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1P0nmZUPMJaPEmYgixoL2QQ?pwd1pc8 提取码&#xff1a;1pc8 注意&#xff1a;此版本没有Linux版&#xff01; 编译gma的Linux虚拟机没有时间修复&#xff0c;本期Linux版…

QT信号与槽/窗口组件优化/使用QT制作QQ登录界面

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断u界面上输入的账号是否为"admin"&#xff0c;…

2024.6.14 作业 xyt

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c…

【面试干货】Integer 和 int 的区别

【面试干货】Integer 和 int 的区别 1、基本类型与包装类型2、内存占用3、自动装箱与拆箱4、null 值5、常量池6、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java中&#xff0c;Integer 和 int 是两种不同类型的变量&#xff0c;…

在k8s中部署Elasticsearch高可用集群详细教程

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Elasticsearch简介 2、为什么在k8s中部署elasti…

【团队成长】2024-24周周报-第一次组会人员分工48期推文预告

大家好&#xff01;我们是IndustryOR 团队&#xff0c;致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎/CSDN【运筹匠心】 。 记录人&#xff1a;张哲铭&#xff0c;算法专家&#xff0c;某互联网大厂 【团队成长/个人成长】系列的推文会以 【工作周报】 的方式记录Ind…

视频信号发生器上位机

在液晶屏测试、电视机信号测试、视频处理器测试中&#xff0c;经常需要使用视频信号发生器&#xff0c;市场上专业的视频信号发生器通常需要大几千元&#xff0c;多则上万元&#xff0c;而且设备测试仪器是一套硬件&#xff0c;没有办法像软件一样复制传播。所以我开发了一套基…

机器视觉:工业镜头的主要参数

工业镜头是图像采集系统的重要光学设备。它的作用是将目标物体的像成在相机的感光面上。 一、工业镜头原理 镜头是对光线进行调制和变换&#xff0c;使目标能够成像到相机的感光芯片上。将不同折射率的硝材加工成高精度的曲面&#xff0c;再把这些曲面进行组合后设计成能够满…

LogicFlow 学习笔记——2. LogicFlow 基础 实例

LogicFlow 实例 创建实例 每一个流程设计界面&#xff0c;就是一个 LogicFlow 的实例。 <template><div id"container"></div><!-- 用于显示 LogicFlow 图表的容器 --> </template> <script>// 创建 LogicFlow 实例const lf …

中文版svn怎么忽略文件

个人需求&#xff1a; 不上传dist&#xff0c;dist.7z&#xff0c;node_modules等文件夹 实际操作&#xff1a; 前言&#xff1a;在上传svn为避免操作失败导致丢失文件的情况&#xff0c;保险起见&#xff0c;先备份代码 1&#xff1a;右键点击 2&#xff1a;点击新建 – 其…

C++初学者指南第一步---4.基本类型

C初学者指南第一步—4.基本类型 文章目录 C初学者指南第一步---4.基本类型1.变量声明2.快速概览Booleans 布尔型Characters 字符型Signed Integers 有符号整数Unsigned Integers 无符号整数Floating Point Types 浮点数类型 3.Common Number Representations 常用的数字表示常用…