数据结构初阶--链表OJⅡ

news2025/1/19 11:25:51

目录

  • 前言
  • 相交链表
    • 思路分析
    • 代码实现
  • 环形链表
    • 思路分析
    • 代码实现
  • 环形链表Ⅱ
    • 思路分析
    • 代码实现
  • 复制带随机指针的链表
    • 思路分析
    • 代码实现

前言

本篇文章承接上篇博客,继续对部分经典链表OJ题进行讲解

相交链表

先来看题目描述

思路分析

这道题我们还是首先来判断一下链表是否相交,即看两条链表的最后一个节点是否为同一个如果不相交,则返回空,如果相交,则进行下一步。
如果两条链表相交,我们可以考虑让较长的链表走它们的长度差步使得两条链表此时的长度一样,然后再同时走直到两条链表的节点指向同一块区域,这个节点就是相交点

代码实现

代码实现如下

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* tailA=headA;
    int lenA=0;
    struct ListNode* tailB=headB;
    int lenB=0;
    while(tailA)
    {
        tailA=tailA->next;
        lenA++;
    }
    while(tailB)
    {
        tailB=tailB->next;
        lenB++;
    }
    if(tailA!=tailB)
    {
        return NULL;
    }
    int tmp=abs(lenA-lenB);
    struct ListNode* llisthead=lenA>lenB?headA:headB;
    struct ListNode* slisthead=lenA>lenB?headB:headA;
    while(tmp--)
    {
        llisthead=llisthead->next;
    }
    while(1)
    {
        if(llisthead==slisthead)
        {
            break;
        }
        llisthead=llisthead->next;
        slisthead=slisthead->next;
    }
    return llisthead;

}

环形链表

先来看题

思路分析

这道题我们采用快慢指针的思路,这样如果是环形链表,当快指针和慢指针都进入环时,快指针总能与慢指针遇到,为保证效率和可实现度,我们让快指针一次走两步,慢指针一次走一步。 如果快指针指向空快指针的下一个节点也指向空(因为要保证快指针能一次走两步),说明该链表并没有形成环

代码实现

代码如下

bool hasCycle(struct ListNode *head) {
    if(head==NULL)
    return false;
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&slow&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        return true;
    }
    return false;
}

环形链表Ⅱ

这道题是上一道题的变式,也借鉴了上一题的思路。
来看题

思路分析

我们还是按照上一题的解题思路判断链表是否形成了环。如果没有则返回空,如果是环形链表我们继续进行下一步。

在确定存在环时,此时快指针和慢指针正好相遇,实际上,此时头节点到链表进入环的节点的距离和此时快/慢指针到链表进入环的结点的距离相等所以此时我们只需要让头指针快/慢指针同时走到相遇时,即为我们要找的节点。

代码实现

代码实现如下

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(fast==slow)
        {
            while(slow!=head)
            {
                slow=slow->next;
                head=head->next;
            }
            return head;
        }
    }
    return NULL;

}

复制带随机指针的链表

思路分析

这道题的本意是让我们复制一次这个链表,我们这里采用的思路是就在原有的链表上操作,1,先在每一个节点后复制一个一样的节点,2,再把所有复制出来的节点与原链表断开,3,再链接起来,这样我们就可以得到一个和原链表一摸一样的新链表了,虽然思路听起来很简单,但是想要真正弄清楚里面所有指针到底该指向哪里,同时又要避免野指针的情况出现,还是非常有难度的,下面我把操作分为三部分来讲解。

  1. 在每一个节点后复制一个一模一样的节点链接起来
    首先我们可以先判断一下链表是否为空,如果为空,就直接返回空指针,否则我们按下图进行操作:(以三个节点为例)

  2. 把所有复制出来的节点有原链表断开

  3. 最后将复制出来的节点连接再一次即可。

代码实现

代码实现如下

struct Node* copyRandomList(struct Node* head) {
   if(head==NULL)
   {
       return NULL;
   }
   for(struct Node* cur=head;cur!=NULL;cur=cur->next->next)
   {
       struct Node* newnode=(struct Node*)malloc(sizeof(struct Node));
       newnode->val=cur->val;
       newnode->next=cur->next;
       cur->next=newnode;
   }
   for(struct Node* cur=head;cur!=NULL;cur=cur->next->next)
   {
       struct Node* newnode=cur->next;
       newnode->random=(cur->random!=NULL)?cur->random->next:NULL;
   }
   struct Node* newhead=head->next;
   for(struct Node* cur=head;cur!=NULL;cur=cur->next)
   {
       struct Node* newnode=cur->next;
       cur->next=cur->next->next;
       newnode->next=(newnode->next!=NULL)?newnode->next->next:NULL;
   }
   return newhead;
}

以上就是本章全部内容,如有出入,欢迎大佬指正。

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

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

相关文章

蓝牙耳机怎么挑选?小编分享2023畅销蓝牙耳机排行榜

蓝牙耳机怎么挑选?蓝牙、音质、续航、佩戴是蓝牙耳机选购时最重要的四大维度,这几年随着技术的成熟体验有了很大改善,但挑选的时候仍然要仔细对比,不然容易踩雷。小编根据销量整理了蓝牙耳机排行榜,一起看看最受消费者…

水务行业数智化招标采购系统建设解决方案

水务行业数智化采购解决方案 国家“十四五”规划和2035年远景目标纲要:提升产业链供应链现代化水平。加快数字化发展,推动产业数字化,数字产业化,以数字化转型整体驱动生产方式、生活方式和治理方式变革。利用数字技术重构价值链…

kafka-Producer Sender 源码分析

说明 本文基于 kafka 2.7 编写。author blog.jellyfishmix.com / JellyfishMIX - githubLICENSE GPL-2.0 Sender 类属性 public class Sender implements Runnable {private final Logger log;/*** Sender 具体用的是 KafkaClient 接口的实现类 NetworkClient, 为 Sender 提…

【算法】经典背包问题

作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下来🐾 文章目录 引入Dp1.01背包2.完全背包3.多重背包4.分组背包 acwing 背包问题——学习笔记 01背包、完全背包、多重背包、分组背包 引入Dp Dp问题&#…

[SUCTF 2018]GetShell

有个文件上传,给了部分源码 if($contentsfile_get_contents($_FILES["file"]["tmp_name"])){$datasubstr($contents,5);foreach ($black_char as $b) {if (stripos($data, $b) ! false){die("illegal char");}} } 可以知道有…

黑白照片如何变彩色?黑白照变彩色的秘诀分享。​

黑白照片如何变彩色?将黑白照片变成彩色可以给照片增添生动的视觉效果和真实感,使得人物、场景更加具体形象,让人们更容易与之产生共鸣和情感联系,此外,通过给黑白老照片添加颜色,还可以打破时间和空间的限…

社区分享|JumpServer引领我走向开源天地

编者注:以下内容基于山东青岛的JumpServer社区用户JonnyJ的社区分享整理而成。 “接触到JumpServer之后,我从一个开源受益者逐渐成长为开源的贡献者。其实我们每个人都可以成为开源贡献者,不局限于软件产品,哪怕只是你的一段共享…

K8S集群+kubeadm+flannel+docker+harbor实例

目录 第一章.环境准备 1.1.部署架构图 1.2.节点要求 1.3.部署软件 1.4.修改主机名 1.5.所有节点修改hosts文件 1.6.关闭防火墙规则,关闭selinux,关闭swap交换 1.7.调整内核参数 第二章.部署K8S集群 2.1.所有节点安装docker 2.2.所有节点安装ku…

KVM管理-快照

KVM管理-快照 创建快照 为虚拟机vm1创建一个快照 [rootmyserver ~]# virsh snapshot-create-as vm1 vm1.snap Domain snapshot vm1.snap created快照只能使用qcow2创建,raw格式一般无法创建快照 查看磁盘镜像信息 [rootmyserver ~]# qemu-img info /var/lib/lib…

方案设计——食物测温仪方案

食物测温仪,在食物烹饪时,温度和时间至关重要,所以食物测温仪孕育而生,当用户使用时只需将食物测温仪的探头插入食物中,即刻能得到当前食物温度数据,不必用经验判断。做为一款食物测温仪,运用场…

Spring Boot :统一功能处理

在用户登陆验证的业务中,如果只是使用Spring AOP的话,session无法获取的,还有各种参数(request等)很难获取,这时候Spring拦截器就发挥了重大的作用了。 1.Spring 拦截器 创建拦截器分俩步:1.创…

项目集效益管理

项目集效益管理是定义、创建、最大化和交付项目集所提供的效益的绩效领域。 本章内容包括: 1 效益识别 2 效益分析和规划 3 效益交付 4 效益移交 5 效益维持 项目集效益管理包括一系列对项目集的成功极为重要的要素。项目集效益管理包括阐明项目集的 计划效益和预期…

AMBER分子动力学模拟之结果分析(最低能量结果)-- HIV蛋白酶-抑制剂复合物(3)

AMBER分子动力学模拟之结果分析(最低能量结果)-- HIV蛋白酶-抑制剂复合物(3) 在analysis目录下 解析.out文件 下载process_mdout.perl 脚本 perl process_mdout.perl ../md/md0.out ../md/md1.out ../md/md2.out # 可以不使用md0.out # 或者 $AMBERHOME/bin/process_md…

ShardingSphere 5.3 系列ShardingSphere-Proxy保姆级教程 | Spring Cloud 50

一、前言 通过以下系列章节: Spring Boot集成ShardingSphere实现数据分片(一) | Spring Cloud 40 Spring Boot集成ShardingSphere实现数据分片(二) | Spring Cloud 41 Spring Boot集成ShardingSphere实现数据分片&…

Linux:centos:组账户管理 》》添加组,用户加入组(设置组密码),删除组,查询账户信息,查询登录用户信息

/etc/group # 组信息文件 /etc/gshadow # 组密码文件(不常用) groupadd (属性) 组名 # 新建组 groupdel (属性) 组名 # 删除组 gpasswd # 可以…

Cartographer源码阅读---番外篇: Submap封装与维护

Cartographer中Submap(子图)没有被直接的调用进行维护, 而是针对2D和3D场景分别派生出子类Submap2D和Submap3D, 进行调用. 以2D为例, 为了方便维护, 又把Submap2D封装成了ActiveSubmaps2D进行维护, 其维护方式类似与滑窗, 也是只维护最近的一些数据. 1. Submap类 /*** brief …

Python学习之生成带logo背景图的二维码(静态和动态图)

前言 二维码简称 QR Code(Quick Response Code),学名为快速响应矩阵码,是二维条码的一种,由日本的 Denso Wave 公司于 1994 年发明。现随着智能手机的普及,已广泛应用于平常生活中,例如商品信息…

探索三维世界【4】:Three.js dat.gui gsap 的使用

探索三维世界【4】:Three.js & dat.gui & gsap 的使用 1、dat.gui是什么?2、gsap的介绍与使用2.1、前提准备工作(绘制一个BoxGeometry)2.2、安装引入gsap动画库2.3、使用gsap动画2.4、配合事件使用 3、使用dat.gui3.1、添…

生物信息学知识点

生物信息学知识点 1. 序列比对:1.1 基本概念:1.2 全局比对和局部比对:1.3 空位罚分的改进:1.4 同源性和相似性:1.5 相似性矩阵:1.5.1 PAM:1.5.2 BLOSUM: 2. BLAST算法:2.…