当前位置: 首页 > news >正文

234. 回文链表 LeetCode 热题 HOT 100

目录

    • 过程解析
      • 1. 问题背景
      • 2. 算法核心思路
      • 3. 快慢指针寻找中点
        • 快慢指针原理
        • 示例 1(奇数长度)
        • 示例 2(偶数长度)
      • 4. 翻转后半部分链表
        • 翻转示例(以偶数链表 1 → 2 → 2 → 1 为例)
      • 5. 比较两部分节点值
      • 6. 可选:恢复链表
      • 7. 复杂度分析
    • 代码
      • C++
      • C语言

过程解析

1. 问题背景

本题要求判断一个单链表是否为回文链表(Palindrome Linked List),即链表从前往后读和从后往前读的值序列完全相同。
例如:

  • 输入:1 → 2 → 2 → 1,输出:true
  • 输入:1 → 2 → 3 → 2 → 1,输出:true
  • 输入:1 → 2,输出:false

2. 算法核心思路

该算法采用 快慢指针 + 翻转后半部分 + 双指针比较 的方式:

  1. 使用快慢指针(fast, slow)找到链表中点。
  2. 从中点开始翻转链表的后半部分。
  3. 从头部与后半部分同时向后比较节点值,若完全相同则为回文。

3. 快慢指针寻找中点

快慢指针原理
  1. slow 每次走 1 步
  2. fast 每次走 2 步

当循环结束时:

  • 若链表长度为 奇数slow 指向中间节点;
  • 若链表长度为 偶数slow 指向后半部分的第一个节点。
示例 1(奇数长度)

链表:1 → 2 → 3 → 2 → 1

步骤slowfast说明
初始11两者都在头节点
第1次循环23slow走1步,fast走2步
第2次循环31(最后一个)slow走到中间节点
循环结束slow = 3fast = nullptr找到中点(3)

此时 slow 正好指向中间节点(3),后半部分为 2 → 1

示例 2(偶数长度)

链表:1 → 2 → 2 → 1

步骤slowfast说明
初始11两者都在头节点
第1次循环22slow走1步,fast走2步
第2次循环2(第二个)nullptr循环结束
结果slow = 第二个2fast = nullptrslow 指向后半段起点

此时后半部分为 2 → 1,前半部分为 1 → 2


4. 翻转后半部分链表

slow 开始,将后半部分链表原地翻转。
核心思想是:逐步反转 next 指针的方向,让链表“反着连”。

  1. 暂存下一个节点
  2. 当前节点反向指向前一个节点
  3. prev 前进到当前节点
  4. curr 前进到下一个节点

翻转完成后,prev 将指向翻转后的新表头(即原链表的尾部)。

翻转示例(以偶数链表 1 → 2 → 2 → 1 为例)

初始:

1 → 2 → 2 → 1↑slow

翻转步骤:

步骤操作翻转后局部结构prevcurr
1翻转节点 2(第二个)2 → nullptr21
2翻转节点 11 → 2 → nullptr1nullptr

最终结果:

前半段:1 → 2
后半段(翻转后):1 → 2

现在链表后半部分被独立翻转,prev 指向翻转后的新头节点(原尾节点)。


5. 比较两部分节点值

设置两个指针:p1,p2

逐节点比较:

  • 若任意一对节点值不同,则不是回文;
  • 若所有对应节点都相同,则为回文。

注意:当链表长度为奇数时,前半段包括中间节点,所以应该以后半段长度为基准遍历


6. 可选:恢复链表

原理同 4
若希望不破坏原链表结构,可再次翻转后半部分恢复原状。


7. 复杂度分析

  • 时间复杂度: O(n)
    (找中点 O(n/2) + 翻转 O(n/2) + 比较 O(n/2))
  • 空间复杂度: O(1)
    (只使用常数级指针)

代码

C++

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:bool isPalindrome(ListNode* head) {// 当节点数量为 0 或 1 时,直接返回 trueif(!head || !head->next) return true;// 使用快慢指针找到链表中点// slow 每次走一步,fast 每次走两步// 当 fast 到达链表末尾时,slow 位于中点ListNode *slow = head, *fast = head;while(fast && fast->next){slow = slow->next;         // 慢指针走一步fast = fast->next->next;   // 快指针走两步}// 循环结束时,slow 指向后半段的起点(若链表长度为奇数,则是中间节点)// 翻转后半段链表// 示例:原链表 1→2→3→2→1// slow 指向第二个“3”处,翻转后半段得到:1→2→3←2←1ListNode *curr = slow, *prev = nullptr;while(curr){ListNode *nextNode = curr->next; // 暂存下一个节点curr->next = prev;               // 反转指针方向prev = curr;                     // prev 向后移动curr = nextNode;                 // curr 向后移动}// 翻转结束后,prev 指向翻转后的新表头(原链表的尾部)bool isPalin = true;  // 用于记录是否为回文// 比较前半段与翻转后的后半段// p1 从头开始,p2 从后半段(翻转后的起点)开始ListNode *p1 = head;ListNode *p2 = prev;while(p2){ // 只需比较后半部分长度即可if(p1->val != p2->val){  // 若任意节点值不同,则不是回文isPalin = false;break;}p1 = p1->next;p2 = p2->next;}// 可选步骤:恢复链表原状// 若不希望破坏原链表结构,可再次反转后半部分恢复/*curr = prev;prev = nullptr;while(curr){ListNode * nextNode = curr->next;curr->next = prev;prev = curr;curr = nextNode;}*/// 返回结果return isPalin;}
};

C语言

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool isPalindrome(struct ListNode* head) {if(!head||!head->next) return true;struct ListNode *fast = head,*slow = head;while(fast&&fast->next){slow = slow->next;fast = fast->next->next;}struct ListNode *prev = NULL,*curr = slow;while(curr){struct ListNode *nextNode = curr->next;curr->next = prev;prev = curr;curr = nextNode;}bool isPalind = true;struct ListNode *p1 = head,*p2 = prev;while(p2){if(p1->val!=p2->val){isPalind = false;break;}p1 = p1->next;p2 = p2->next;}/*curr = prev;prev = NULL;while(curr){struct ListNode *nextNode = curr->next;curr->next = prev;prev = curr;curr = nextNode;}*/return isPalind;
}
http://www.dtcms.com/a/454761.html

相关文章:

  • 淘宝网站建设可行性分析电子商务实现技术
  • 怎么做捐款网站更改wordpress前缀
  • snipaste免费版下载安装教程
  • 湖南网站设计外包费用wordpress批量添加tag
  • 郑州网站建设yipinpai枣庄网站开发招聘
  • 启动网站建设的请示115做网站
  • 网站运营案例巅云建站
  • 南宁做网站公司品牌云尚网络免费做团购网站的软件
  • 长春专业做网站公司排名一站式网站建设平台
  • C++ 数字
  • 找人做网站流程梅州生态建设有限公司网站
  • 做网站需要学会哪些欧米茄官方网站
  • 海思Hi3516CV610/Hi3516CV608开发笔记之环境搭建和SDK编译
  • 【开题答辩实录分享】以《病虫害监测管理系统的设计与实现》为例进行答辩实录分享
  • 网站注册模板国外优秀画册设计网站
  • 淄博品质网站建设网站开发的教学视频
  • C语言模拟面向对象编程方法之继承
  • jsp网站开发教学视频教程网站服务器租用报价
  • 西安网站建设品牌公司推荐网站建设 网页设计需要技能
  • 做端口映射 怎么访问网站南京百度网站排名
  • 【深度学习新浪潮】从“机械执行“到“智能决策“:大模型与办公Agent的融合实践
  • 网站备案和服务器备案吗常熟智能网站开发
  • 【量化开发】从0到1实现自己的量化算子系统
  • 扬中网站建设开发网站先做前台还是后台
  • 如何百度搜到自己网站免费素材免费下载
  • 自己搞网站建设wordpress 4.2.2 漏洞
  • 深圳自适应网站公司wordpress慕课
  • 扩散模型DDPM数学推导过程完整版(上)
  • 兰州网站seo外包详情页设计与制作
  • 单电源运放的使用