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

这篇具有很好参考价值的文章主要介绍了【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言 

目录

1、题目介绍

2、解题思路

2.1、暴力破解法

2.2、快慢指针反转链表


【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

 文章来源地址https://www.toymoban.com/news/detail-713940.html

1、题目介绍

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

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

示例 1:

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

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

示例 2:

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

输入: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. 返回结果。

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

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

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

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

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

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

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言

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

 代码实现:

/**
 * 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的next
        n2->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博客https://blog.csdn.net/zzzzzhxxx/article/details/133942678?spm=1001.2014.3001.5501【LeetCode力扣】297. 二叉树的序列化与反序列化-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/133827375【LeetCode力扣】LCR170 使用归并排序的思想解决逆序对问题(详细图解)_Hacynn的博客-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/133578735

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表,LeetCode刷题,leetcode,链表,算法,数据结构,开发语言,c++,c语言 

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

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

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

 

到了这里,关于【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LeetCode算法小抄 -- 链表(快慢指针、双指针、回文链表)

    ⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计10077字,阅读大概需要10分钟 🌈更多学习内容, 欢迎👏关注👀文末我的个人微信公众号:不懂开发的程序猿 个人网站:https://jerry-jy.co/ Collection 子接口之 Queue (LeetCode上经常用,手撕算法题!

    2023年04月08日
    浏览(27)
  • LeetCode - 142. 环形链表 II (C语言,快慢指针,配图)

            如果你对快慢指针,环形链表有疑问,可以参考下面这篇文章,了解什么是环形链表后,再做这道题会非常简单,也更容易理解下面的图片公式等。 LeetCode - 141. 环形链表 (C语言,快慢指针,配图)-CSDN博客         上述文章总结: 如果一个链表是环形链表,采用

    2024年02月05日
    浏览(39)
  • 【leetcode 力扣刷题】字符串翻转合集(全部反转///部分反转)

    题目链接:344. 反转字符串 题目内容: 题目中重点强调了必须 原地修改 输入数组,即不能新建一个数组来完成字符串的反转。我们注意到: 原来下标为0的,反转后是size - 1【原来下标是size - 1的,反转后是0】; 原来下标是1的,反转后是size - 2【原来下标是size -2的,反转后

    2024年02月11日
    浏览(34)
  • Leetcode刷题之反转链表Ⅱ

    业精于勤而荒于嬉,行成于思而毁于随。                      ——韩愈 目录 前言: 🍁一.反转链表Ⅱ 🍒1.left和right中间链表反转,再把反转链表和剩下的链接起来 🗼2.left和right中间链表头插  题目描述: 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left =

    2024年02月04日
    浏览(29)
  • LeetCode | 一探环形链表的奥秘【快慢双指针妙解BAT等大厂经典算法题】

    前言 本文总结了力扣141.环形链表|以及142.环形链表||这两道有关环形链表的求解方案,去求证链表是否带环已经如何找出入环口的结点。 有关环形链表,在BAT等大厂面试中均有出现,一般是属于 中等难度 的题,需掌握 原题传送门 给你一个链表的头节点 head ,判断链表中是

    2024年02月01日
    浏览(34)
  • 力扣每日一道系列 --- LeetCode 206. 反转链表

    📷 江池俊: 个人主页 🔥个人专栏: ✅数据结构探索 ✅LeetCode每日一道 🌅 有航道的人,再渺小也不会迷途。 LeetCode 206. 反转链表 初始化两个指针, cur 和 newhead 。 cur 指向给定的链表头节点, newhead 初始为 NULL 。 在 cur 不为空的情况下,执行循环。 首先,记录下 cur 的下

    2024年02月04日
    浏览(31)
  • 反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】

    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 这里解释一下三个指针的作用: n1:记录上一个节点,如果是第一个就指向空 n2:记录此节点的位置 n3:记录下一个节点的位置,让翻转后能找到下一个节点

    2024年02月03日
    浏览(38)
  • 【刷题笔记8.15】【链表相关】LeetCode:合并两个有序链表、反转链表

    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 示例 2: 输入:l1 = [], l2 = [] 输出:[] 示例 3: 输入:l1 = [], l2 = [0] 输出:[0] 此题没啥好说的,直接上代码,自己好好分析

    2024年02月12日
    浏览(33)
  • 刷题日记 Day 3 : Leetcode 203 . 移除链表元素、Leetcode 707 . 设计链表、Lettcode 206 . 反转链表

    本篇文章 , 是在代码随想录 60 天编程挑战的基础上进行的题目讲解 参与链接在此 : https://programmercarl.com/other/xunlianying.html 大家好 , 这个专栏 , 给大家带来的是 60 天刷题强训 . 最令大家头疼的事就是刷题了 , 题目又臭又长又抽象 , 有的题读都读不懂 , 更别说做了 . 所以 , 这个

    2023年04月09日
    浏览(39)
  • 【leetcode 力扣刷题】链表基础知识 基础操作

    在数据结构的学习过程中,我们知道线性表【一种数据组织、在内存中存储的形式】是线性结构的,其中线性表包括顺序表和链表。数组就是顺序表,其各个元素在内存中是连续存储的。 链表则是由 数据域 和 指针域 组成的 结构体 构成的,数据域是一个节点的数据,指针域

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包