单链表进阶算法题精析

news2024/11/24 10:02:39

目录

一、回文链表

1.1 题目

1.2 题解

1.3 分析

二、带环链表I

2.1 题目

2.2 题解

2.3 分析

2.3.1为什么该思路可行?

2.3.2为什么只能快指针走两步?

三、带环链表II

3.1 题目

3.2 题解

3.3 分析

四、相交链表

4.1 题目

4.2 题解

4.3 分析

4.3.1如何判断是相交链表

4.3.2如何返回相交节点

4.4第三题的相交链表新思路

五、面试题—链表的深度拷贝

5.1 题目

5.2 题解

5.3 分析


一、回文链表

1.1 题目

牛客网原题链接:链表的回文结构_牛客题霸_牛客网

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

1.2 题解

class PalindromeList {
  public:
    //寻找中间节点
    struct ListNode* middleNode(struct ListNode* head) {
        struct ListNode* slow = head;
        struct ListNode* fast = head;
        while (fast != NULL && fast->next != NULL) {
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }
    //逆置链表
    struct ListNode* reverseList(struct ListNode* head) {
        if (head == NULL) {
            return head;
        }
        struct ListNode* a = NULL;
        struct ListNode* b = head;
        struct ListNode* c = head->next;

        while (b) {
            b->next = a;
            a = b;
            b = c;
            if (c) {
                c = c->next;
            }
        }
        return a;
    }
    //
    bool chkPalindrome(ListNode* A) {
        struct ListNode* mid = middleNode(A);
        struct ListNode* rmid = reverseList(mid);

        while(rmid&&A)
        {
            if(rmid->val!=A->val)
            {
                return false;
            }

            rmid=rmid->next;
            A = A->next;
        }

        return true;
    }
};

1.3 分析

找到中间节点,将中间节点往后的节点进行逆置,然后从中间节点开始遍历之后的节点与头节点进行比较。

寻找中间节点使用快慢指针法,逆置链表用三指针法。具体讲解详见博主的另一篇博客:http://t.csdnimg.cn/1mZ1x

二、带环链表I

2.1 题目

LeetCode原题链接:. - 力扣(LeetCode)

给你一个链表的头节点 head ,判断链表中是否有环。如果链表中存在环 ,则返回 true 。 否则,返回 false 。

2.2 题解

bool hasCycle(struct ListNode *head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)
        {
            return true;
        }
    }
    return false;
}

2.3 分析

2.3.1为什么该思路可行?

2.3.2为什么只能快指针走两步?

三、带环链表II

3.1 题目

LeetCode原题链接:. - 力扣(LeetCode)

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

3.2 题解

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)
        {
            struct ListNode* meet = slow;
            while(meet!=head)
            {
                meet=meet->next;
                head=head->next;
            }
            return meet;
        }
    }
    return false;
}

3.3 分析

四、相交链表

4.1 题目

LeetCode原题链接:. - 力扣(LeetCode)

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

4.2 题解

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA=headA,*curB=headB;
    struct ListNode* plong=headA,*pshort=headB;
    int kA=0;
    int kB = 0;
    while(curA->next)
    {
        curA=curA->next;
        kA++;
    }
    while(curB->next)
    {
        curB=curB->next;
        kB++;
    }
    if(curA!=curB)
    {
        return NULL;
    }
    int cha = abs(kA-kB);
   
    if(kA<kB)
    {
        plong = headB;
        pshort=headA;
    }
    while(cha--)
    {
        plong=plong->next;
    }
    while(plong!=pshort)
    {
        plong=plong->next;
        pshort=pshort->next;
    }
    return plong;
}

4.3 分析

4.3.1如何判断是相交链表

两个链表的尾指针指向的是同一个节点

4.3.2如何返回相交节点

难点:相交前的两个链表长度可能不同,不能从头开始一一比较

解决方案:将长链表的指针率先走,走到长度与短链表的指针相同为止。

采用快慢指针法。详见博主的另一篇博客:http://t.csdnimg.cn/1mZ1x

4.4第三题的相交链表新思路

五、面试题—链表的深度拷贝

5.1 题目

LeetCode原题链接:. - 力扣(LeetCode)

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

5.2 题解

struct Node* copyRandomList(struct Node* head) {
	struct Node* cur = head;
    //创建复制节点
    while(cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        //尾插到原节点之后
        copy->next = cur->next;
        cur->next=copy;

        cur=copy->next;
    }
    cur = head;
    //复制随机指针
    while(cur)
    {
        struct Node* copy = cur->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }

        cur=copy->next;
    }
    cur = head;
    //构建新链表并返回
    struct Node* copyhead=NULL;
    struct Node* copytail=NULL;
    while(cur)
    {
        struct Node* copy = cur->next;

        
        if(copyhead==NULL)
        {
            copyhead=copytail=copy;
        }
        else
        {
            copytail->next=copy;
            copytail=copytail->next;
        }
        

        cur=copy->next;
    }
    return copyhead;
}

5.3 分析

难点:随机指针的指向问题

解决方案:  

     1. 复制一个全新链表,根据原链表的相对位置,确定随机指针的指向,时间复杂度为O(N^2)

     2.将每个新节点全部尾插到原节点的后面,这样只需将random指向原节点的next的指针即可

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

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

相关文章

uniapp:K线图,支持H5,APP

使用KLineChart完成K线图制作,完成效果: 1、安装KLineChart npm install klinecharts2、页面中使用 <template><view class="index"><!-- 上方选项卡 --><view class="kline-tabs"><view :style="{color: current==ite…

git出错、文件无法删除、文件无法访问、文件或目录损坏且无法读取 等相关问题处理

一、错误历程与解决方案 1. 在用idea时&#xff0c;突然出现 部分git的命令无法使用&#xff0c;提示错误 2. 尝试删除项目文件夹&#xff0c;重新从git拉取代码 3.发现无法删除文件夹&#xff0c;删除操作没有任何反应&#xff0c;但是可以对文件夹重命名。 4.重新clone g…

【哈希】Leetcode 219. 存在重复元素 II

题目讲解 219. 存在重复元素 II 算法讲解 class Solution { public:bool containsNearbyDuplicate(vector<int>& nums, int k) {map<int, int>Hash;for(int i 0; i < nums.size(); i){//这一步说明前面已经出现过一次这样的数字了&#xff0c;所以用后面…

Android Studio的button点击事件

xml添加onClick调用方法 public class MainActivity extends AppCompatActivity {// 创建系统时间的文本控件TextView systemTimeTextView;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activit…

Docker基本操作 Linux里边操作

docker镜像操作命令: docker images:查看所有镜像; docker rmi:删除镜像 后边可以跟镜像的名字或者id指定要删除的镜像&#xff1b; docker pull:拉取镜像&#xff1b; docker push:推送镜像到服务&#xff1b; docker save :打包镜像 后边有用法; docker load:加载镜像&…

岚图汽车与东软睿驰签署战略合作协议

4月26日,东软睿驰与岚图汽车正式签署战略合作协议,双方将结合在各自领域拥有的产业资源、技术研发和资本运作等优势,聚焦智能化产品和应用,建立长期共赢的战略合作伙伴关系,通过不断探索未来新技术、新产业、新业态和新模式,围绕用户需求共同打造极致的智能出行体验。 图为岚图…

linux,从零安装mysql 8.0.30 ,并且更新至mysql 8.0.36

前言&#xff1a; 系统使用的CentOS 7&#xff0c;系统默认最小安装。 一、基础配置 配置虚拟机IP&#xff0c;需要更改的内容&#xff0c;如下红框中 修改之后 至此&#xff0c;基础配置完成。注意&#xff1a;此处虚拟机网络适配器使用的是&#xff1a;桥接模式 二、软件…

虚拟DOM

虚拟DOM&#xff08;Virtual DOM&#xff09;是现代前端框架&#xff08;如React、Vue等&#xff09;用于优化DOM操作性能的关键技术。Vue也采用了虚拟DOM来提高性能和提供更好的开发体验。以下是虚拟DOM在Vue中的详细解释&#xff1a; 什么是虚拟DOM&#xff1f; 虚拟DOM是一…

【分治算法】【Python实现】棋盘覆盖

文章目录 [toc]问题描述分治算法时间复杂性Python实现 个人主页&#xff1a;丷从心 系列专栏&#xff1a;分治算法 学习指南&#xff1a;Python学习指南 问题描述 在一个 2 k 2 k 2^{k} \times 2^{k} 2k2k个方格组成的棋盘中&#xff0c;若恰有一个方格与其他方格不同&…

vue3插槽的name和v-slot的研究

slot可以分为具名插槽和默认,默认插槽name是default 在父组件的template需要些v-slot/#,没写不生效,而在父组件下,而没被template包含的默认放在template且含有#default. 1)没写slot,可以不写template,也可写default的template2)写了name的slot,即使是default也必须些template…

STM32(垃圾桶开关盖)

封装超声波的代码 一、配置引脚的连接 二、配置 三、写代码 四、配置定时器 查找合适的定时器 其实这里的是remap&#xff08;复用&#xff09;&#xff0c;不重要 重要的是看Default才对 仔细查看之后发现还是能用的 先把开关灯封装好 再封装舵机 ----------------------…

谷粒商城实战(019 RabbitMQ-发送消息)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第248p-第p261的内容 介绍 MQ的三大特点&#xff1a;流量削峰、应用解耦、异步处理 redis是数据缓存&#xff0c;mq是任务缓存 AMQP的MODEL 第一…

静电纺丝左旋聚乳酸平行纳米纤维膜

静电纺丝左旋聚乳酸平行纳米纤维膜是一种特殊的纳米材料&#xff0c;它结合了静电纺丝技术的优点和左旋聚乳酸&#xff08;PLLA&#xff09;材料的特性。 静电纺丝技术是一种特殊的纤维制造工艺&#xff0c;在此过程中&#xff0c;高分子溶液或熔体在强电场中进行喷射纺丝。当电…

主成分分析(PCA):揭秘数据的隐藏结构

在数据分析的世界里&#xff0c;我们经常面临着处理高维数据的挑战。随着维度的增加&#xff0c;数据处理、可视化以及解释的难度也随之增加&#xff0c;这就是所谓的“维度的诅咒”。主成分分析&#xff08;PCA&#xff09;是一种强大的统计工具&#xff0c;用于减少数据的维度…

[华为OD]给定一个 N*M 矩阵,请先找出 M 个该矩阵中每列元素的最大值 100

题目&#xff1a; 给定一个 N*M 矩阵&#xff0c;请先找出 M 个该矩阵中每列元素的最大值&#xff0c;然后输出这 M 个值中的 最小值 补充说明&#xff1a; N 和 M 的取值范围均为&#xff1a;[0, 100] 示例 1 输入&#xff1a; [[1,2],[3,4]] 输出&#xff1a; 3 说…

数据仓库实验二:关联规则挖掘实验

目录 一、实验目的二、实验内容和要求三、实验步骤1、创建数据库和表2、挖掘关联规则&#xff08;1&#xff09;新建一个 Analysis Services 项目 Sales&#xff08;2&#xff09;建立数据源视图&#xff08;3&#xff09;建立挖掘结构 Sales.dmm&#xff08;4&#xff09;部署…

FebHost:什么是挪威.no域名,如何注册?

挪威国家域名介绍 挪威是一个位于北欧的国家&#xff0c;北面和西面是大西洋和北海&#xff0c;东面和南面则与瑞典、芬兰接壤。挪威是一个高度发达的经济体&#xff0c;其政府在经济管理和可持续发展方面也取得了很多成就。挪威的人均GDP在世界范围内排名非常靠前&#xff0c…

C# Web控件与数据感应之 ListControl 类

目录 关于数据感应 ListControl 类类型控件 范例运行环境 数据感应通用方法 设计 实现 调用示例 数据源 调用 小结 关于数据感应 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;Web控件与数据源之间的交互&#xff0c;诸如 System.Web.UI.WebControls 里…

Anddroid系统APK卸载流程源码分析

这一章我们介绍APK的卸载过程&#xff0c;大致了解这里的卸载的过程如下&#xff1a; 1.从PMS的内部结构上删除acitivity、service、provider等信息 2.删除code、library和resource等信息 3.调用installd删除/data/data/packageName以及/data/dalvik-cache下面的文件 4.更新Set…

python学习笔记----函数(五)

一、函数介绍 在 Python 中&#xff0c;函数是一个组织好的、可重用的代码块&#xff0c;用来执行一个单一的、相关的动作。函数提供了代码的模块化和代码复用的能力。它可以接受输入参数&#xff0c;并可以返回一个结果。函数在 Python 编程中是基本的构建块之一。 二、函数…