单链表OJ题

单链表OJ题(文字解读 + 图解)

  • 1. 移除链表元素
  • 2. 反转链表
  • 3. 链表的中间结点
  • 4. 返回倒数第 k 个节点
  • 5. 合并两个有序链表

1. 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
OJ链接=>

struct ListNode* removeElements(struct ListNode* head, int val)

这题当然可以暴力遍历,将值一一对比,相等的删除,并重新链接。但还有更优的思路:

  1. 定义两个指针(slow,fast);
  2. fast先走,如果fast指向的val和其相等,则让slow指向fast的下一个后fast再走;如果不相等,则让slow指向fast指向的位置后发射台再走;
  3. 最后再分一些特殊情况。
    图解
struct ListNode* removeElements(struct ListNode* head, int val) {
    
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    //头为空,直接返回空
    if(head == NULL)
        return  NULL;
    while(fast)
    {
        if(fast->val == val)
        {
            slow->next = fast->next;
            fast = fast->next;
        }
        else
        {
            slow=fast;
            fast=fast->next;
        }
    } 
    //当头结点就是val时并且头结点下一个结点为空,直接返回空
    if(head->val == val&&head->next==NULL)
        return NULL;
    //当头结点就是val时并且头结点下一个结点不去为空,直接返回头节点的下一个节点
    else if(head->val == val&&head->next!=NULL)
        return head->next;
    else 
        return head;
}

最后一定要分情况,不然OJ有些测试用例通过不了。

2. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
OJ链接=>

struct ListNode* reverseList(struct ListNode* head)

这题的最优解:

  1. 创建3个指针,第一个指针n1指向空,第二个指针n2指向头节点,第三个指针n3指向头节点的下一个节点;
  2. 先将n2指向n1,再让n1指向n2,n2指向n3,再循环往后走;

图解

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = head;
    
    while(n2)
    {
        struct ListNode* n3 = n2->next;
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        
    }
    return n1;
}

最后一次,当n3赋值给n2时,n2指向空,所以循环结束条件n2!=NULL。如果将n3放在循环外创建可能会造成空指针,因为数组可能只有一个元素或者就没有元素,这样n3就没有用了。

3. 链表的中间结点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。
OJ链接=>

struct ListNode* middleNode(struct ListNode* head)

这题还是快慢指针问题:
让一个指针从头节点开始一次走一步,让第二个指针从头节点开始一次走两步,走到尾时,慢指针刚好走到中间节点。
图解

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

当节点个数为奇数个时,循环终止条件为fast->next != NULL;当节点个数为偶时,循环终止条件为fast != NULL,将两种情况合并。

4. 返回倒数第 k 个节点

实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
OJ链接=>

int kthToLast(struct ListNode* head, int k)

这是一道经典的面试题,最优思路为:先让一个指针从头节点走k步,再让一个指针从头节点开始和前一个指针同时走,当走到尾,慢指针指向的就是我们要的。
在这里插入图片描述

int kthToLast(struct ListNode* head, int k){
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(k--)
    {
        fast = fast->next;
    }
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow->val;
}

循环结束条件为当fast == NULL.

5. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
OJ链接=>

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2);

解题思路:
此题可以先创建一个空链表,然后依次从两个有序链表中选取最小的进行尾插操作进行合并。
在这里插入图片描述

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode* head = NULL,*tail = NULL;
    //特殊情况先出
    if(list1 == NULL)
    {
        return list2;
    }
    if(list2 == NULL)
    {
        return list1;
    }
    
    while(list1 && list2)
    {
        if(list1->val < list2->val)
        {
        	//第一次插入
            if(tail == NULL)
            {
                head = tail = list1;
            }
            else
            {
            	//后续取较小的尾插
                tail->next = list1;
                tail = tail->next; 
            }
            list1 = list1->next;
        }
        else
        {
            if(tail == NULL)
            {
                head = tail = list2;
            }
            else
            {
                tail->next = list2;
                tail = tail->next; 
            }
            list2 = list2->next;
        }
    }
    //当list2走完,list1还有节点时直接尾插
    if(list1)
    {
        tail->next = list1;
    }
    //当list1走完,list2还有节点时直接尾插
    if(list2)
    {
        tail->next = list2;
    }
    return head;
}

单链表没有这么简单,目前程度我做不来难题,后续有机会再更新.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Obsidian使用200+插件与70+种主题分享

主题资源 下载方式一&#xff1a; 网盘下载 密码:a3eu 下载方式二&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fOgP8lY29sYxkUAbTlQQCw 提取码&#xff1a;qhxa 下载解压打开红色框文件夹 上面的是插件&#xff0c;下面的是主题 以下介绍安装主题 打开Obsidi…

【小白笔记:JetsonNano学习(一)SDKManager系统烧录】

参考文章&#xff1a;SDKManager系统烧录 小白烧录文件系统可能遇到的问题 担心博主删除文章&#xff0c;可能就找不到比较详细的教程了&#xff0c;特意记录一下。 Jetson Nano采用四核64位ARM CPU和128核集成NVIDIA GPU&#xff0c;可提供472 GFLOPS的计算性能。它还包括4GB…

Linux信号灯

目录 一、什么是信号量 二、PV操作概念 三、信号灯 四、有名信号灯 五、无名信号灯 一、什么是信号量 线程的信号量与进程间通信中使用的信号量的概念是一样&#xff0c;它是一种特殊的变量&#xff0c;它可以被增加或减少&#xff0c;但对其的关键访问被保证是原子操作。…

搜索二叉树迭代和递归的两种*简单*实现方式

判断搜索二叉树 概念 一棵树所有结点的左节点小于父节点&#xff0c;右节点大于父节点&#xff0c;则为搜索二叉树。 迭代方法 中序遍历二叉树&#xff0c;如果总是升序则是搜索二叉树。如果存在降序&#xff0c;那肯定不是搜索二叉树。 Coding checkTreeOrder()方法 boo…

js判断对象是否有某个属性

前端判断后端接口是否返回某个字段的时候 <script>var obj { name: "John", age: 30 };console.log(obj.hasOwnProperty("name")); // 输出 trueconsole.log(obj.hasOwnProperty("email")); // 输出 falselet obj11 { name: "Joh…

DNF的概念和操作命令

yum是linux系统中基于rpm包管理的一种软件管理工具。 在dnf.conf文件中&#xff0c;我们可以配置某个网络服务器位软件源仓库。配置的方法&#xff0c;就是用vim编辑/etc/dnf/dnf.conf这个文件。

数字化转型导师坚鹏:人工智能在金融机构数字化转型中的应用

人工智能在金融机构数字化转型中的应用 课程背景&#xff1a; 金融机构数字化转型离不开人工智能&#xff0c;在金融机构数字化转型中&#xff0c;人工智能起到至关重要的作用&#xff0c;很多机构存在以下问题&#xff1a; 不清楚人工智能产业对我们有什么影响&#xff1f;…

Netty学习——源码篇2 客户端Bootstrap(一) 备份

1 Channel简介 在Netty中&#xff0c;Channel相当于一个Socket的抽象&#xff0c;它为用户提供了关于Socket状态&#xff08;是连接还是断开&#xff09;以及对Socket的读写等操作。每当Netty建立了一个连接&#xff0c;都创建一个与其对应的Channel实例。 除了TCP&#xff0c;…

考研数学|跟武忠祥,刷什么习题集效果最好?

选择听哪位老师的课程并不是硬性规定。我个人觉得&#xff0c;关键在于根据自己的学习需求和情况来选择合适的学习方式。比如如果听武忠祥老师的课程可能更适合你&#xff0c;你可以选择武忠祥老师&#xff1b;而如果你希望通过大量的题目练习来提高解题能力&#xff0c;那么选…

IntelliJ IDEA 设置运行时环境变量

背景 博主要测试langchain4j&#xff0c;运行时需要OPENAI_BASE_URL和OPENAI_API_KEY这两个环境变量的值。 临时设置 Run -> Edit Configurations -> Edit Environmental Variables 永久设置 在系统环境变量中设置&#xff0c;教程无数。 注意&#xff1a;windows在…

进程地址空间的进一步认识

进程地址空间 地址空间的大小取决于系统的架构和操作系统的实现。在32位系统中&#xff0c;地址空间大小为2的32次方&#xff08;约为4GB&#xff09;。而在64位系统中&#xff0c;地址空间大小为2的64次方。 进程地址空间的划分使得不同的数据和代码可以在不同的区域中进行管…

IM项目题

消息协议 消息的可靠性 前言 IM系统的可靠性指的是端到端的可靠性&#xff0c;并不是tcp的可靠性&#xff0c;它是指客户端A&#xff0c;客户端B以及服务端三端通信之间的可靠性&#xff0c;并不是客户端A到服务端这么一个上行消息的可靠&#xff0c;这个tcp就可以保证了&#…

洛谷 P1378 油滴扩展

本道题可以理解成一个平面直角坐标系&#xff0c;在坐标系上标出整个矩形和油滴的坐标&#xff0c;计算两个油滴的面积和直径&#xff0c;判断点是否在圆内&#xff08;点与圆的位置关系&#xff09;&#xff0c;利用使用坐标求两点间距离的公式取解。 代码如下&#xff1a; …

定位及解决OOM

一、定义 内存溢出&#xff1a;OutOfMemoryError&#xff0c;是指因内存不够&#xff0c;导致操作新对象没有剩余空间。会导致频繁fullgc出现STW从而导致性能下降。 内存泄漏&#xff1a;指用malloc或new申请了一块内存&#xff0c;但是没有通过free或delete将内存释放&#…

一维坐标的移动(bfs)

在一个长度为n的坐标轴上&#xff0c;小S想从A点移动B点。 他的移动规则如下&#xff1a; 向前一步&#xff0c;坐标增加1。 向后一步&#xff0c;坐标减少1。 跳跃一步&#xff0c;使得坐标乘2。 小S不能移动到坐标小于0或大于n的位置。 小S想知道从A点移动到B点的最少步数是多…

四.排序(冒泡/选择)

目录 11-排序介绍 常见排序算法: 12-冒泡排序介绍 代码要求: 思路: 13-冒泡排序 代码: 14-选择排序 简单写法: 好的写法: 11-排序介绍 排序&#xff1a;将一组“无序”的记录序列调整为“有序”的记录序列。 列表排序&#xff1a;将无序列表变为有序列表 输入&#…

LeetCode 2312.卖木头块:动态规划(DP)

【LetMeFly】2312.卖木头块&#xff1a;动态规划(DP) 力扣题目链接&#xff1a;https://leetcode.cn/problems/selling-pieces-of-wood/ 给你两个整数 m 和 n &#xff0c;分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices &#xff0c;其中 prices[i] [hi, …

SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程…

面试经典150题(114-118)

leetcode 150道题 计划花两个月时候刷完之未完成后转&#xff0c;今天完成了5道(114-118)150 gap 了一周&#xff0c;以后就不记录时间了。。 114.(70. 爬楼梯) 题目描述&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不…

【CTF笔记】 CTF web方向笔记分享 免费 附预览图

个人不怎么记东西&#xff0c;笔记不多&#xff0c;师傅们凑合看… 百度网盘&#xff1a;https://pan.baidu.com/s/1PspihUX28Y_AOQZPurHqKA 麻烦各位师傅帮忙填写一下问卷&#xff0c;提取码在问卷填写结束后显示~ 【https://www.wjx.cn/vm/mBBTTKm.aspx# 】 &#xff08;…