初阶数据结构:链表相关题目练习(补充)

news2025/2/23 22:57:37

目录

  • 1. 单链表相关练习题
    • 1.1 移除链表元素
    • 1.2 反转链表
    • 1.3 链表的中间结点
    • 1.4 链表的倒数第k个结点
    • 1.5 合并两个有序链表
    • 1.6 链表分割
    • 1.7 链表的回文结构
    • 1.8 相交链表
    • 1.9 判断一个链表中是否有环
    • 1.10 寻找环状链表相遇点
    • 1.11 链表的深度拷贝

1. 单链表相关练习题

注:单链表结构上存在一定缺陷,所以链表相关的题目一般都针对与单链表。

1.1 移除链表元素

题目要求:在这里插入图片描述
题目信息:

  1. 头节点head
  2. 移除值val

题目链接:
移除链表元素

方法(顺序处理法):

思路:分析链表结构与结点所处的位置(是否为空链表,结点是否为头结点),分情况依次处理。

过程演示:
在这里插入图片描述

struct ListNode* removeElements4(struct ListNode* head, int val)
{
	struct ListNode* pre = NULL;
	struct ListNode* cur = head;

	while (cur)
	{
		if (cur->val == val)
		{
			//头删
			if (cur == head)
			{
				head = head->next;
				free(cur);
				cur = head;
			}
			else//中间删
			{
				pre->next = cur->next;
				free(cur);
				cur = pre->next;
			}
		}
		else
		{
			pre = cur;
			cur = cur->next;
		}
	}

	return head;
}

1.2 反转链表

题目要求:
在这里插入图片描述
题目链接:
反转链表

过程演示:

struct ListNode* reverseList(struct ListNode* head) 
{
    struct ListNode* pre = NULL;
    struct ListNode* mid = head;
    struct ListNode* cur = NULL;

    if(head)
    {
        cur = head->next;
    }

    while(mid)
    {
        mid->next = pre;
        pre = mid;
        mid = cur;
        if(cur)
        {
            cur = cur->next;
        }
    }

    return pre;
    
}

1.3 链表的中间结点

题目要求:
在这里插入图片描述
题目链接:
链表的中间结点

过程演示(快慢指针法):

struct ListNode* middleNode(struct ListNode* head) 
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;

    while(fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
    }

    return slow;
}

1.4 链表的倒数第k个结点

题目要求:
在这里插入图片描述
题目链接:
倒数第k个结点

过程演示:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) 
{
    struct ListNode* cur = pListHead;
    struct ListNode* pre = pListHead;
    while(cur && k--)
    {
        cur = cur->next;
    }

    if(k > 0)
    {
        pre = NULL;
    }

    while(cur)
    {
        pre = pre->next;
        cur = cur->next;
    }

    return pre;
}

1.5 合并两个有序链表

题目要求:
在这里插入图片描述
题目链接:
合并两个链表

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
    struct ListNode* newhead = NULL;
    struct ListNode* cur = NULL;
    struct ListNode* newnode = NULL;

    if(list1 == NULL)
        return list2;

    if(list2 == NULL)
        return list1;

    while(list1 != NULL && list2 != NULL)
    {
        if(list1->val <= list2->val)
        {
            newnode = list1;
            list1 = list1->next;
        }
        else
        {
            newnode = list2;
            list2 = list2->next;
        }
        
        if(newhead == NULL)
        {
            newhead = newnode;
            newnode->next = NULL;
            cur = newhead;
        }
        else
        {
            //在遍历过程中,list1 或 list2 会等于 NULL
            cur->next = newnode;
            if(newnode != NULL)
            {
                newnode->next = NULL;
                cur = cur->next;
            }
        }
    }

    //有一个链表本就为空
    if(list1)
    {
        cur->next = list1;
    }

    if(list2)
    {
        cur->next = list2;
    }

    return newhead;
}

1.6 链表分割

题目要求:
在这里插入图片描述
题目链接:
合并两个链表

ListNode* BuyNewNode(int val)
    {
        ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
        newnode->val = val;
        newnode->next = nullptr;

        return newnode;
    }

    ListNode* partition(ListNode* pHead, int x) 
    {
        ListNode* newhead1 = nullptr;
        ListNode* end1 = nullptr;
        ListNode* newhead2 = nullptr;
        ListNode* end2 = nullptr;
        ListNode* cur = pHead;
        while(cur)
        {
            if(cur->val < x)
            {
                if(newhead1 == nullptr)
                {
                    newhead1 = BuyNewNode(cur->val);
                    end1 = newhead1;             
                }
                else 
                {
                    end1->next = BuyNewNode(cur->val);
                    end1 = end1->next;
                }
            }
            else 
            {
                if(newhead2 == nullptr)
                {
                    newhead2 = BuyNewNode(cur->val);
                    end2 = newhead2;             
                }
                else 
                {
                    end2->next = BuyNewNode(cur->val);
                    end2 = end2->next;
                }
            }
            cur = cur->next;
        }

        if(newhead1 == nullptr)
        {
            newhead1 = newhead2;
        }
        else 
        {
            end1->next = newhead2;
        }

        return newhead1;
    }

1.7 链表的回文结构

题目要求:
在这里插入图片描述
题目链接:
回文串

ListNode* reverse(ListNode* head)
    {
        ListNode* pre = nullptr;
        ListNode* mid = head;
        ListNode* cur = head->next;
        while (mid)
        {
            mid->next = pre;
            pre = mid;
            mid = cur;
            if (cur)
            {
                cur = cur->next;
            }
        }

        return pre;
    }

    bool chkPalindrome(ListNode* A)
    {
        //找相同,逆置
        //逐点比较
        //回文结构存在奇数个结点

        //获取中间结点
        ListNode* fast = A;
        ListNode* slow = A;
        while(fast && fast->next)
        {
            fast = fast->next->next;
            if(fast)
            {
                slow = slow->next;
            }
        }

        //表1
        ListNode* newhead2 = slow->next;
        //表2
        slow->next = nullptr;
        ListNode* newhead1 = reverse(A);
        if(fast)
        {
            newhead1 = newhead1->next;
        }


        while (newhead1 && newhead2 && newhead1->val == newhead2->val)
        {
            newhead1 = newhead1->next;
            newhead2 = newhead2->next;
        }

        if (newhead1 == nullptr && newhead2 == nullptr)
        {
            return true;
        }

        return false;
    }

1.8 相交链表

题目要求:
在这里插入图片描述题目链接:
相交链表

void swap(struct ListNode** node1, struct ListNode** node2)
{
    struct ListNode* tmp = *node1;
    *node1 = *node2;
    *node2 = tmp;
}

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    struct ListNode* short_list1 = headA;
    struct ListNode* short_list2 = headA;
    struct ListNode* long_list1 = headB;
    struct ListNode* long_list2 = headB;

    while(short_list1 && long_list1)
    {
        short_list1 = short_list1->next;
        long_list1 = long_list1->next;
    }

    if(short_list1)
    {
        swap(&short_list1, &long_list1);
        swap(&short_list2, &long_list2);
    }

    while(long_list1)
    {
        long_list1 = long_list1->next;
        long_list2 = long_list2->next;
    }

    //while((short_list2 && long_list2) || short_list2 != long_list2)
    while(short_list2 && long_list2 && short_list2 != long_list2)
    {
        long_list2 = long_list2->next;
        short_list2 = short_list2->next;
    }

    return short_list2;
}

1.9 判断一个链表中是否有环

题目要求:
在这里插入图片描述
题目链接:
判断是否有环

//逻辑步骤存疑
bool hasCycle(struct ListNode *head) 
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;
	
	//err: while(fast && slow != fast)
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(slow == fast)
        {
            return true;
        }
    }

    return false;
}

1.10 寻找环状链表相遇点

题目要求:
在这里插入图片描述
题目链接:
寻找环状链表相遇点

思路依靠结论:一个结点从起始点,一个结点从相遇点(快慢指针相遇点),以同速行走(一次走一步),当他们再一次初次相遇时,此相遇结点即为入环点。

struct ListNode *detectCycle(struct ListNode *head) 
{
    //快慢指针确定首次相遇点
    //起始点与相遇点出发,同速移动,最后的相遇的点即为环的进入点
    struct ListNode* fast = head;
    struct ListNode* slow = head;

    //遍历寻找相遇点
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;

        if(fast == slow)
        {
            break;
        }
    }
	
	//判断是否为环状链表
    if(fast == NULL || fast->next == NULL)
    {
        return NULL;
    }

    slow = head;
    while(fast != slow)
    {
        fast = fast->next;
        slow = slow->next;
    }

    return fast;
}

1.11 链表的深度拷贝

题目要求:
在这里插入图片描述>题目链接:
链表的深度拷贝

//思路:
//生成拷贝结点
//调整拷贝结点的指针
//还原原链表,链接拷贝结点
struct Node* BuyNewNode(int val)
{
    struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
    newnode->val = val;
    newnode->next = NULL;
    newnode->random = NULL;

    return newnode;
}

struct Node* copyRandomList(struct Node* head)
{
    struct Node* node1 = head;
	//判断是否为空链表
    if(head == NULL)
    {
        return head;
    }
    //创建新节点
    while (node1)
    {
        struct Node* newnode = BuyNewNode(node1->val);
        newnode->next = node1->next;
        node1->next = newnode;

        node1 = node1->next->next;
    }

    //调整新节点的随机指针
    struct Node* node2 = head->next;
    node1 = head;
    while (node2)
    {
        if (node1->random)
        {
            node2->random = node1->random->next;
        }

        node1 = node1->next->next;
        if (node2->next)
        {
            node2 = node2->next->next;
        }
        else
        {
            node2 = node2->next;
        }
    }

    //还原链表,链接新链表
    node1 = head;
    node2 = head->next;
    struct Node* newhead = head->next;
    while (node1)
    {
        node1->next = node1->next->next;
        if (node2->next)
        {
            node2->next = node2->next->next;
        }

        node1 = node1->next;
        node2 = node2->next;
    }

    return newhead;
}

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

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

相关文章

低功耗微处理器复位检测电路D706,工作温度范围-40~+80℃,可与μP监控产品兼容

近年来&#xff0c;微处理器在IT业控制领域和智能化产品中得到了广泛的应用。在系统和产品的开发设计过程中&#xff0c;为了提高其抗干扰能力&#xff0c;使用μP监控是首选技术措施之一。监控芯片可为系统提供上电、掉电复位功能&#xff0c;也可提供其它功能&#xff0c;如后…

SpringBoot 自定义注解实现操作日志记录

文章目录 前言正文一、项目结构介绍二、核心类2.1 核心注解2.1.1 CLog 日志注解2.1.2 ProcessorBean 处理器bean 2.2 切面类2.3 自定义线程池2.4 工具类2.4.1 管理者工具类 2.5 测试2.5.1 订单创建处理器2.5.2 订单管理者2.5.3 订单控制器2.5.4 测试报文2.5.5 测试结果 附录1、…

Docker部署前后端服务示例

使用Docker部署js前端 1.创建Dockerfile 在项目跟目录下创建Dockerfile文件&#xff1a; # 使用nginx作为基础镜像 FROM nginx:1.19.1# 指定工作空间 WORKDIR /data/web# 将 yarn build 打包后的build文件夹添加到工作空间 ADD build build# 将项目必要文件添加到工作空间&a…

【Python】FastAPI 项目创建 与 Docker 部署

文章目录 前言&需求描述1. 本地FastAPI1.1 Python 环境准备1.2 本地 Pycharm 创建FastAPI项目 2. Python FastAPI 部署2.1 服务器配置Python环境2.2.1 下载与配置Git、Pyenv等工具2.2.2 下载与配置Python 2.2 FastAPI 打包成镜像2.2.1 项目准备所需环境文件2.2.2 编写Docke…

python matplotlib 三维实体圆柱图

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np from mpl_toolkits.mplot3d import Axes3D import matplotlib.ticker as tickerdef map_rate(X: list, to_min: float, to_max: float)…

Restful风格解释

示例对比 传统风格开发 Restful风格开发 结论&#xff1a; 传统风格开发中&#xff0c;前端不同操作使用不同的url来访问后端&#xff0c;使得访问变得麻烦restful风格中&#xff0c;前端使用相同的url来访问后端&#xff0c;但是用数据传送方式进行区分&#xff08;get为请求…

DataGrip2023配置连接Mssqlserver、Mysql、Oracle若干问题解决方案

1、Mssqlserver连接 本人连的是Sql2008&#xff0c;默认添加时&#xff0c;地址、端口、实例、账号、密码后&#xff0c;测试连接出现错误。 Use SSL&#xff1a;不要勾选 VM option&#xff1a;填写&#xff0c;"-Djdk.tls.disabledAlgorithmsSSLv3, RC4, DES, MD5withR…

c#使用log4net的3种调用方法

https://blog.csdn.net/summer_top/article/details/107961245 第一步&#xff1a;下载log4net。 右键项目引用&#xff0c;进入管理NuGet包。 搜索log4net&#xff0c;下载安装。 第二步&#xff1a;创建LogHelper类。 public class LogHelper { private LogHelp…

说一说kong日志级别

Kong官网&#xff1a;The Platform Powering the API World | Kong Inc. Kong Gateway&#xff1a;Kong Gateway | Kong Docs Kong Admin API&#xff1a;Admin API - Kong Gateway - v3.4.x | Kong Docs Kong 企业版社区&#xff1a;API Community for Developers and Industr…

ad18学习笔记十六:如何放置精准焊盘到特定位置,捕抓功能的讲解

网上倒是一堆相关的指导 AD软件熟练度提升&#xff0c;如何设置板框捕捉&#xff1f;_哔哩哔哩_bilibili 关于Altium Designer 20 的捕抓功能的讲解_ad捕捉设置-CSDN博客 AD软件捕捉进阶实例&#xff0c;如何精确的放置布局元器件&#xff1f;_哔哩哔哩_bilibili AD绘制PCB…

android游戏开发大全pdf,赶紧学起来

面经分享 第一部分是我前端面试的经验总结&#xff0c;第二部分是我认为比较有思考空间的题目 经验总结 一份漂亮的简历&#xff0c;需要包括以下部分&#xff08;排版由上而下&#xff09; 个人亮点&#xff08;专精领域&#xff0c;个人博客&#xff0c;开源项目&#xff09…

jmeter 压测数据库

当前版本&#xff1a; jmeter 5.6.3mysql 5.7.39 简介 JMeter 是一个开源的 Java 应用程序&#xff0c;主要用于进行性能测试和负载测试。它支持多种协议&#xff0c;包括但不限于 HTTP、HTTPS、FTP、JDBC 以及各种 Web Services。对于数据库的压力测试可以使用 JDBC 协议与数…

Python算法题集_组合总和

Python算法题集_组合总和 题39&#xff1a;组合总和1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【值传递回溯】2) 改进版一【引用传递堆栈回溯】3) 改进版二【过程值列表缓存遍历后检索】 4. 最优算法5. 相关资源 本文为Python算法题集之一的…

【办公类-22-07】周计划系列(3-2)“信息窗+主题知识(优化)” (2024年调整版本)

作品展示&#xff1a; 背景需求 前文对“2023年2月”的一套信息窗主题知识的文件系列&#xff0c;进行第一次的提取。获得基础模板。 【办公类-22-07】周计划系列&#xff08;3-1&#xff09;“信息窗主题知识&#xff08;提取&#xff09;” &#xff08;2024年调整版本&…

面试官问我Redis怎么测,我哪知道!

有些测试朋友来问我&#xff0c;redis要怎么测试&#xff1f;首先我们需要知道&#xff0c;redis是什么&#xff1f;它能做什么&#xff1f; redis是一个key-value类型的高速存储数据库。 redis常被用做&#xff1a;缓存、队列、发布订阅等。 所以&#xff0c;“redis要怎么测试…

理解计算着色器中glsl语言的内置变量

概要 本文通过示例的方式&#xff0c;着重解释以下几个内置变量&#xff1a; gl_WorkGroupSizegl_NumWorkGroupsgl_LocalInvocationIDgl_WorkGroupIDgl_GlobalInvocationID 基本概念 局部工作组与工作项 一个3x2x1的局部工作组示例如下&#xff0c;每个小篮格子表示一个工作项…

简单了解B树和B+树

目录 B树 B树 B树和B树的结构示意图 总结 B树和B树是两种非常重要的树状数据结构&#xff0c;它们广泛应用于数据库和文件系统的索引结构中。这两种数据结构能够帮助我们高效地管理、查询以及更新大量的数据。下面&#xff0c;我将简单介绍它们,以及他们之间的区别。 B树 B…

【leetcode】链表的中间节点

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 点击查看题目 思路: slow和fast都初始化为head&#xff0c;之后slow每走1步&#xff0c;fast走2步…

枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)

目录 一、枚举算法介绍 二、解空间的类型 三、循环枚举解空间 四、例题 &#xff08;一、反倍数&#xff09; &#xff08;二、特别数的和&#xff09; &#xff08;三、找到最多的数&#xff09; &#xff08;四、小蓝的漆房&#xff09; &#xff08;五、小蓝和小桥的…

【力扣hot100】刷题笔记Day17

前言 今天竟然不用开组会&#xff01;天大的好消息&#xff0c;安心刷题了 46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 回溯&#xff08;排列&#xff09; class Solution:def permute(self, nums: List[int]) -> List[List[int]]:# 回溯def backtrack():if len(…