【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表

 

目录

1、题目介绍

2、解题思路

2.1、暴力破解法

2.2、快慢指针反转链表


 

1、题目介绍

原题链接: 234. 回文链表 - 力扣(LeetCode)

示例 1:

输入:head = [1,2,2,1]
输出:true 

示例 2:

输入:head = [1,2]
输出:false 

提示: 

  • 链表中节点数目在范围[1, 10^5] 内
  • 0 <= Node.val <= 9

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

2、解题思路

判断回文,就是判断是否是对称的。有些朋友对于数组的回文判断非常熟悉,但是对链表的回文判断可能就无从下手了,其实都一样的。有一种非常简单的方式就是将链表转化成数组,然后就是判断该数组是否回文就可以了,这种方式统称暴力破解法,简单粗暴。下面就来先带着大家看一下这道题的暴力破解法

2.1、暴力破解法

一共为两个步骤:

  1. 复制链表值到数组列表中。
  2. 使用双指针法判断是否为回文。

首先按照题目要求的最大大小定义一个大小为100001的整型数组,接着通过循环遍历将链表中每个结点的值取出放入数组中,最后通过两个指针,一个从左一个从右分别判断是否相等,只要遇到一个不相等就返回false,否则当循环结束时返回true。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool isPalindrome(struct ListNode* head){int arr[100001] = {0},num = 0;while(head){arr[num] = head->val;head = head->next;num++;}int i= 0;int j =0;for(i = 0,j = num-1; i<j; i++,j--){if(arr[i]!=arr[j]){return false;}}return true;
}

时间复杂度:O(n),其中 n 指的是链表的元素个数。

  • 第一步:遍历链表并将值复制到数组中,O(n)。
  • 第二步:双指针判断是否为回文,执行了 O(n/2) 次的判断,即O(n)。
  • 总的时间复杂度:O(2n)=O(n)。

空间复杂度:O(n),其中 n 指的是链表的元素个数,我们使用了一个数组列表存放链表的元素值。

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

下面带大家做一下本题的进阶,使用快慢指针反转链表实现空间复杂度为O(1)的算法。

2.2、快慢指针反转链表

整个流程可以分为以下五个步骤:

  1. 找到前半部分链表的尾节点。
  2. 反转后半部分链表。
  3. 判断是否回文。
  4. 恢复链表。
  5. 返回结果。

对于第一步找到前半部分链表的尾结点,我们可以计算链表结点个数然后再找到前半部分的尾结点,也可以通过快慢指针一次遍历找到前半部分的尾结点。

慢指针一次走一步,快指针一次走两步,快慢指针同时出发。当快指针移动到链表的末尾时,慢指针恰好到链表的中间。通过慢指针将链表分为两部分。

此时slow就是前半部分的尾结点,而slow的下一个结点就是后半部分的头结点。于是让fast回到slow的next结点处,将后半部分的结点全部反转,然后slow即前半部分的尾结点置空。

紧接着将让slow从head重新出发,fast从最后结点出发,分别向中间结点靠近并判断,只要相等就一直向中间靠近,遇到不相同时直接返回false,否则当循环退出时返回true。

最后在将反转链表还原回去即可。 

 代码实现:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool isPalindrome(struct ListNode* head){if(head == NULL || head->next == NULL){return true;}struct ListNode* n1 = head;struct ListNode* n2 = head;//快慢指针遍历while(n2->next != NULL && n2->next->next != NULL){n1 = n1->next;          //慢指针n2 = n2->next->next;    //快指针 }n2 = n1->next;   //右边第一个n1->next = NULL;struct ListNode* n3;//反转右半边链表while(n2 != NULL){n3 = n2->next;  //n3存放n2的nextn2->next = n1;n1 = n2;n2 = n3;}//当循环结束时n1所指向的位置就是链表最后一个结点,n2 = n3 = n1;  //将n2和n3指回最后一个节点n1 = head;     //n1回到头结点bool flag = true;//判断是否是回文while(n1 != NULL && n2 != NULL){if(n1->val != n2->val){flag = false;break;}n1 = n1->next;n2 = n2->next;}//还原链表n2 = n3->next;    //n3此时指向最后一个结点,因为反转了链表,n3的next就是上一个结点n3->next = NULL;while(n2!=NULL){n1 = n2->next;n2->next = n3;n3 = n2;n2 = n1;}return flag;
}

时间复杂度:O(n),其中 n 指的是链表的大小。

空间复杂度:O(1)。我们只会修改原本链表中节点的指向,而在堆栈上的堆栈帧不超过 O(1)。

 更多【LeetCode刷题】 推荐:

【LeetCode力扣】86. 分隔链表-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/133942678?spm=1001.2014.3001.5501【LeetCode力扣】297. 二叉树的序列化与反序列化-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/133827375【LeetCode力扣】LCR170 使用归并排序的思想解决逆序对问题(详细图解)_Hacynn的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/133578735

 

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决使用WebTestClient访问接口报[185c31bb] 500 Server Error for HTTP GET “/**“

解决使用WebTestClient访问接口报[185c31bb] 500 Server Error for HTTP GET "/**" 问题发现问题解决 问题发现 WebTestClient 是 Spring WebFlux 框架中提供的用于测试 Web 请求的客户端工具。它可以不用启动服务器&#xff0c;模拟发送 HTTP 请求并验证服务器的响…

2023最新UI酒桌喝酒游戏小程序源码 娱乐小程序源码 带流量主

2023最新UI酒桌喝酒游戏小程序源码 娱乐小程序源码 带流量主 修改增加了广告位&#xff0c;根据文档直接替换&#xff0c;原版本没有广告位 直接上传源码到开发者端即可 通过后改广告代码&#xff0c;然后关闭广告展示提交&#xff0c;通过后打开即可 无广告引流 流量主版…

Jupyter Notebook 设置黑色背景主题

Jupyter Notebook 设置黑色背景主题 # 包安装 pip install jupyterthemes -i https://mirrors.aliyun.com/pypi/simple pip install --upgrade jupyterthemes # 查看可用主题 jt -l # monokai暗背景&#xff0c;-f(字体) -fs(字体大小) -cellw(占屏比或宽度) -ofs(输出段的字…

Spark内核调度

目录 一、DAG &#xff08;1&#xff09;概念 &#xff08;2&#xff09;Job和Action关系 &#xff08;3&#xff09;DAG的宽窄依赖关系和阶段划分 二、Spark内存迭代计算 三、spark的并行度 &#xff08;1&#xff09;并行度设置 &#xff08;2&#xff09;集群中如何规划并…

HTML+CSS+JS+Django 实现前后端分离的科学计算器、利率计算器(附全部代码在gitcode链接)

&#x1f9ee;前后端分离计算器 &#x1f4da;git仓库链接和代码规范链接&#x1f4bc;PSP表格&#x1f387;成品展示&#x1f3c6;&#x1f3c6;科学计算器&#xff1a;1. 默认界面与页面切换2. 四则运算、取余、括号3. 清零Clear 回退Back4. 错误提示 Error5. 读取历史记录Hi…

HTTP响应

HTTP响应分为四个部分&#xff1a; 首行&#xff1a;HTTP/1.1&#xff08;首行&#xff09; 200&#xff08;状态码&#xff09; OK&#xff08;状态码描述&#xff09;header&#xff1a;空行&#xff1a;表示header的结束标记body&#xff1a;正文 HTTP状态码&#xff1a;…

C#实现数据导出任一Word图表的通用呈现方法及一些体会

疲惫的修改 应人才测评产品的需求&#xff0c;导出测评报告是其中一个重要的环节&#xff0c;报告的文件类型也多种多样&#xff0c;其中WORD输出也扮演了一个重要的角色。 实现方法比较简单&#xff0c;结合分析结果数据&#xff0c;通过WORD模板文件进行替换输出。在实现的…

BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain

BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain----《BadNets:识别机器学习模型供应链中的漏洞》 背景&#xff1a; 许多用户将训练过程外包给云计算&#xff0c;或者依赖于经过训练的模型&#xff0c;然后根据特定的任务对模型进行微调。这…

Homeassistant docker配置

Homeassistant docker配置 【说明】本系列为自用教程&#xff0c;记录以便下次使用 【背景】一台J1900 4G64G的小主机&#xff0c;安装了OP系统&#xff0c;里面自带了Docker。为实现Homeassistant&#xff08;简称HA&#xff09;控制智能家居设备&#xff0c;进行如下配置。 【…

改进YOLO系列 | YOLOv5/v7 引入 Dynamic Snake Convolution | 动态蛇形卷积

准确分割拓扑管状结构,如血管和道路,在各个领域中至关重要,可以确保下游任务的准确性和效率。然而,许多因素使任务复杂化,包括细小的局部结构和可变的全局形态。在这项工作中,我们注意到管状结构的特殊性,并利用这一知识来引导我们的DSCNet,以在三个阶段同时增强感知:…

使用反射拼接SQL语句 和 使用 反射 + 注解 拼接SQL语句

以下知识本人都是用 Maven工程 总结的 1、使用反射拼接SQL语句 package com.csdn.anno; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.Properties; public class AnnotationTest {public static void main(Str…

JVM 堆外内存查看方法

JVM 堆外内存查看方法 概述 是否曾经想过为什么Java应用程序通过众所周知的*-Xms和-Xmx调整标志消耗的内存比指定的数量大得多 &#xff1f;由于各种原因和可能的优化&#xff0c;JVM可能会分配额外的本机内存。这些额外的分配最终可能使消耗的内存超出-Xmx* 限制。在本教程中…