趣说数据结构(练习1) —— 顺序表/链表力扣刷题

练习 1 —— 顺序表/链表力扣刷题

1. 合并两个有序链表

力扣题目地址:https://leetcode.cn/problems/merge-two-sorted-lists/

问题描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
在这里插入图片描述

解题思路:

  1. 给定的是一个有序列表,因此不需要重新排序;
  2. 典型的双指针问题,不过此处的双指针分别指两个链表的对应的指针;

解题方法一:

此份代码是通过创建一个新的链表分别存储两个链表组合后的结果。这个方法比较简单,简单来说就是两个步骤,第一步逐个比较,你们俩谁小,谁小就移动谁的指针;第二步收尾,还有谁有剩余的存库,快快交出来。

这份代码是比较 low 的,因为它需要额外开销空间,并且代码看起来多少有点不够美观。

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* result = new ListNode(-1);
        ListNode* point = result;
        while(list1 != nullptr && list2 != nullptr) {
            if(list1->val <= list2->val) {
                point->next = list1;
                list1 = list1->next;
            } else {
                point->next = list2;
                list2 = list2->next;
            }
            point = point->next;
        }
        if (list1 != nullptr) {
            point->next = list1;
        }
        if (list2 != nullptr) {
            point->next = list2;
        } 
        return result->next;
    }
};

解题方法二:

以下代码来自官方文档
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        } else if (l2 == nullptr) {
            return l1;
        } else if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};

比较的简洁美观,看起来也比较舒服,除了 l1l2 这种不太科学的变量命名,读起来还是非常的简单。

  1. 排除二者存在空的情况;
  2. 递归解决问题,每次递归只解决一个问题;
  3. 每次递归返回的数据都是已经完成 “部分合并” 后的结果。

坏处:此份代码使用递归需要申请额外的栈存储空间。

2. 删除排序链表中的重复元素

力扣原题地址:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/

题目描述:给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

题目的示例:
在这里插入图片描述

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

问题分析:抓住关键字:已经排序的链表。

接下来的时间就简单了,我们用一个指针p,不要轻易移动,只有遇到 “与自己不一样” 的小伙伴才移动,自己才能变成它,最终就绕开了重复的元素,实现了去重的目的。

解题方法一:


class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (!head) {
            return head;
        }

        ListNode* now = head;
        while (now -> next) {
        	// 如果遇到的和自己相等,就绕开它到它的next
            if (now -> val == now -> next->val) {
                now -> next = now -> next->next;
            } else {
                // 不一样就保留它,加到自己的队伍
                now = now -> next;
            }
        }

        return head;
    }
};

这个解题方法比较简单,也未申请额外的存储空间,所以时间复杂度为 O ( n ) O(n) O(n),而空间复杂度为 O ( 1 ) O(1) O(1)

3. 反转链表

题目描述

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

示例

在这里插入图片描述

代码实现 1

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* result = new ListNode();
        ListNode* p = result;
        while (head != nullptr) {
            ListNode* q = new ListNode(head -> val);
            q -> next = p -> next;
            p -> next = q;
            head = head -> next;
        }

        return result -> next;
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

时间复杂度已经无法降低,空间复杂度应当有改善空间,如下所示:

代码实现 2

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr != nullptr) {
            ListNode* next = curr -> next;
            curr -> next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
};

时间复杂度:O(n)

空间复杂度:O(1)

这个地方有疑问的小伙伴可以尝试先返回 curr,输出的结果是 [ ],也就是说,之所以能够节省空间,只是我们使用两个指针移来移去的,这里我们绘制一个简单图片描述一下。

在这里插入图片描述
第一步,next = curr -> next 记录一下当前结点的下个结点的位置;
第二步,curr -> next = prev 当前结点指向的下一个结点等于 prev,请看图片中的下面一行图片,也就是说这个时候 prev 准备挪到 2 那个位置了,我们先把 curr -> next = prev,然后 prev = curr,这个时候对应的 prev 已经指向了 2 的位置;
第三步,curr = next,把 curr 拉回正轨。因为刚刚出去协助 prev 指针了,所以这里把它拉回来。

循环前面的步骤,即可完成链表的反转。归根结蒂就是利用指针的灵活性,反过来再写一遍。

有点迷糊

总结

本章的练习部分算是 “小试牛刀”,两个非常简单的题目,用来练练手感受一下使用指针 -> 挪动数据的方法。

Smileyan
2023.04.30 00:25

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

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

相关文章

Java——Java面向对象

该系列博文会告诉你如何从入门到进阶&#xff0c;一步步地学习Java基础知识&#xff0c;并上手进行实战&#xff0c;接着了解每个Java知识点背后的实现原理&#xff0c;更完整地了解整个Java技术体系&#xff0c;形成自己的知识框架。 概述&#xff1a; Java是面向对象的程序…

@Autowired与@Resource原理知识点详解

文章目录 前言springIOC依赖注入的三种方式属性注入&#xff08;字段注入&#xff09;构造方法注入setter注入用哪个&#xff1f; Autowired实现原理 Resource实现原理结论 Autowired与Resource的不同来源不同参数不同使用不同装配顺序 前言 现在spring可以说是一统天下了&…

【Unity-UGUI控件全面解析】| Canvas 画布组件详解

🎬【Unity-UGUI控件全面解析】| Canvas 画布组件详解一、组件介绍1.1 绘制元素的顺序二、组件属性面板2.1 Canvas :画布,控制UI的渲染模式2.2 Canvas Scaler:画布缩放器,控制UI画布的放大缩放的比例2.3 Graphic Raycaster:图形射线投射器,控制是否让UI响应射线点击三、…

【干货分享】一文说透分布式一致性协议(上)

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;大熊老师 | 慕课网讲师 在常见的分布式系统中&#xff0c;总会发生诸如机器宕机或网络异常&#xff08;包括消息的延迟…

数据备份系列:Rsync 备份详解(一)

一、Rsync 简介 1.1 Rsync 是一个远程增量文件备份软件工具 1.2 Rsync 的特性 支持拷贝特殊文件&#xff0c;如连接文件、设备等。可以有排除指定文件或目录同步的功能&#xff0c;相当于打包命令 tar 的排除功能。可以做到保持原文件或目录的权限、时间、软硬链接、属主、组…

Python每日一练(20230502)

目录 1. 被围绕的区域 &#x1f31f;&#x1f31f; 2. 两数之和 II &#x1f31f; 3. 二叉树展开为链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1…

react native ios 添加启动页 xcode14 react-native-splash-screen

最近更新xcode&#xff0c;有些配置有些不同&#xff0c;网上查的方法都是过时的&#xff0c;导致配了一段时间卡在这里&#xff0c;最后访问官网才弄好了&#xff0c;所以以后解决问题的办法先看官网再查其他各路神仙的办法。 官网的步骤&#xff1a;https://github.com/crazy…

颜色空间转换RGB-YCbCr

颜色空间 颜色空间&#xff08;Color Space&#xff09;是描述颜色的一种方式&#xff0c;它是一个由数学模型表示的三维空间&#xff0c;通常用于将数字表示的颜色转换成可见的颜色。颜色空间的不同取决于所选的坐标轴和原点&#xff0c;以及用于表示颜色的色彩模型。在计算机…

【C++入门】一篇搞懂auto关键字

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】 目录 作用不那么大的场景auto真正的价值auto和指针结合使用注意点auto不能推导的场景范围for范围for的使用条件 作用不那么大的…

海尔牵头IEEE P2786国际标准通过Sponsor投票并连任工作组主席

01 海尔牵头IEEE P2786国际标准 通过Sponsor投票 并连任工作组主席 海尔牵头制定的全球首个服装物联网国际标准IEEE P2786《Standard for General Requirements and Interoperability for Internet of Clothing》通过Sponsor投票&#xff0c;标志着该国际标准草案得到了行业…

2.6 浮点运算方法和浮点运算器

学习目标&#xff1a; 以下是一些具体的学习目标&#xff1a; 理解浮点数的基本概念和表示方法&#xff0c;包括符号位、指数和尾数。学习浮点数的运算规则和舍入规则&#xff0c;包括加、减、乘、除、开方等。了解浮点数的常见问题和误差&#xff0c;例如舍入误差、溢出、下…

FPGA实现10G万兆网UDP通信 10G Ethernet Subsystem替代网络PHY芯片 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案传统 FPGA UDP 方案本 FPGA 10G UDP 方案(牛逼)10G Ethernet 框图10G Ethernet 发送解析10G Ethernet 接收解析10G Ethernet 寄存器配置10G Ethernet UI 配置 4、vivado工程详解5、上板调试验证并演示ping功能测试数据收发测…

一款支持全文检索、工作流审批、知识图谱的企事业知识库

一、项目介绍 一款全源码&#xff0c;可二开&#xff0c;可基于云部署、私有部署的企业级知识库云平台&#xff0c;一款让企业知识变为实打实的数字财富的系统&#xff0c;应用在需要进行文档整理、分类、归集、检索、分析的场景。 获取方式q:262086839 为什么建立知识库平台&…

perf record对C++程序耗时进行分析

本节将介绍如何使用perf工具的perf record对C代码进行性能分析&#xff0c;一切操作都是在ubuntu 20下进行。 perf工具安装 由于perf工具和内核版本有关&#xff0c;因此直接安装容易出错&#xff0c;建议直接通过如下指令安装&#xff1a; sudo apt-get install linux-tool…

00后卷王的自述,我难道真的很卷?

前言 前段时间去面试了一个公司&#xff0c;成功拿到了offer&#xff0c;薪资也从12k涨到了18k&#xff0c;对于工作都还没两年的我来说&#xff0c;还是比较满意的&#xff0c;毕竟一些工作3、4年的可能还没我高。 我可能就是大家说的卷王&#xff0c;感觉自己年轻&#xff…

独立IP服务器和共享IP服务器有什么区别

在选择一个合适的服务器时&#xff0c;最常见的选择是共享IP服务器和独立IP服务器。尽管两者看起来很相似&#xff0c;但它们有着很大的不同。本文将详细介绍共享IP服务器和独立IP服务器的不同之处&#xff0c;以及如何选择适合您需求的服务器。 一、什么是共享IP服务器? 共享…

Python探索性P图,四种增强方式快速玩转pillow库

嗨害大家好鸭&#xff01;我是爱摸鱼的芝士❤ 我们平时使用一些图像处理软件时&#xff0c; 经常会看到其对图像的亮度、对比度、色度或者锐度进行调整。 你是不是觉得这种技术的底层实现很高大上&#xff1f; 其实最基础的实现原理&#xff0c; 用 Python 实现只需要几行…

Java JDK下载安装环境变量配置

目录 一、下载安装 1.简介 2.JDK下载JDK 官网海外历史地址&#xff1a; 3.安装 二、环境变量配置 1.新建JAVA_HOME变量 2.PATH变量 3.CLASSPATH 变量 4.测试是否安装成功 一、下载安装 1.简介 JDK 是SUN公司提供的一套Java 语言的软件开发工具包&#xff0c;简称JDK(JavaDevelo…

如何编写高质量代码

如何编写高质量代码 1. 前言2. 明确业务场景和用户需求3. 编程实践技巧3.1 提高命名规范3.2 保持代码简洁3.3 好的注释 4. 软件测试5. 总结 1. 前言 现代软件开发中&#xff0c;代码是构建高质量软件的核心。高质量代码能够提高软件系统的可靠性、可维护性和可扩展性&#xff…

给失业的互联网人一个思路:别再苦苦找工作了,要去找门槛低、现金流好、天花板低、资本看不上的创业项目,一年也能几百万!...

失业大潮中的互联网人该何去何从&#xff1f;这大概是许多人在难捱的深夜反复思考的问题。 一位失业很久的网友就在痛苦思索中悟出了适合自己的道路&#xff0c;下面分享给大家&#xff0c;篇幅太长&#xff0c;小编给大家划一下重点。 先说结论&#xff1a;失业的互联网人别再…