【Leetcode】链表专题

leetcode链表专题

主要根据CSview一个校招刷题准备网站 做这个网站的人真的很厉害!进行整理
太困了,一学习就困,来刷刷题

文章目录

  • leetcode链表专题
  • 前言
  • 一、leetcode 206.反转链表
    • 1.题目描述:
    • 2.主要有两种方法,迭代法和递归法
    • 3.迭代法:
    • 4.递归法:
  • 二、leetcode 83.删除排序链表中的重复元素
    • 1.迭代法解决该问题
    • 2.采用回归的方法来解决
  • 总结


前言

一、leetcode 206.反转链表

1.题目描述:

在这里插入图片描述

2.主要有两种方法,迭代法和递归法

先来描述两者的区别:
迭代法(Iteration)和递归法(Recursion)都是解决问题的方法,它们在编程中经常被用到。

迭代法是通过循环的方式,重复执行某段代码直到满足条件为止。通常使用迭代语句(如for循环或while循环)来实现。迭代法通常比递归法更直观,更容易理解,并且在一些情况下效率更高。它的实现方式类似于人们在日常生活中的思考方式,一步一步地解决问题。

递归法则是指一个函数在执行过程中调用自己的编程技巧。递归的本质是将问题划分为规模更小的子问题,并不断地重复这个过程直到达到最基本的情况,然后逐层返回结果。递归在某些情况下更为简洁,但可能会导致栈溢出或性能问题,因为每次递归调用都会增加函数调用栈的深度。

3.迭代法:

我们可以思考,是否可以通过指针指向位置的交换来实现反转。
定义三个指针:
prev代表在迭代过程中已经反转的头节点,初始值指向null;
curr指向当前节点,也就是待反转部分的头节点。初始值为链表的头节点head;
next指向curr.next节点,当前节点的下一个节点;

prev=null;
curr=head;
next=null;
//交换过程如下:
next=curr.next;
curr.next=prev;
prev=curr;
curr=next;

让我们以具体的示例来描述迭代法中的每个循环。

假设原始链表为:1 -> 2 -> 3 -> 4 -> 5,我们将对其进行反转。

  1. 初始化

    • 初始时,prev = nullcurr = 1next = null
    • 链表状态:prev -> null, curr -> 1 -> 2 -> 3 -> 4 -> 5next -> null
  2. 第一次迭代

    • 进入循环,next 指向 curr.next,即 2
    • 链表状态:prev -> null, curr -> 1 -> null, next -> 2 -> 3 -> 4 -> 5
    • curr.next 指向 prev,即 1next 指向 null
    • 移动 prevcurr 的位置,即 prev -> 1
    • 移动 currnext 的位置,即 curr -> 2
  3. 第二次迭代

    • 进入循环,next 指向 curr.next,即 3
    • 链表状态:prev -> 1 -> null, curr -> 2 -> null, next -> 3 -> 4 -> 5
    • curr.next 指向 prev,即 2next 指向 1
    • 移动 prevcurr 的位置,即 prev -> 2 -> 1
    • 移动 currnext 的位置,即 curr -> 3
  4. 第三次迭代

    • 进入循环,next 指向 curr.next,即 4
    • 链表状态:prev -> 2 -> 1 -> null, curr -> 3 -> null, next -> 4 -> 5
    • curr.next 指向 prev,即 3next 指向 2
    • 移动 prevcurr 的位置,即 prev -> 3 -> 2 -> 1
    • 移动 currnext 的位置,即 curr -> 4
  5. 第四次迭代

    • 进入循环,next 指向 curr.next,即 5
    • 链表状态:prev -> 3 -> 2 -> 1 -> null, curr -> 4 -> null, next -> 5
    • curr.next 指向 prev,即 4next 指向 3
    • 移动 prevcurr 的位置,即 prev -> 4 -> 3 -> 2 -> 1
    • 移动 currnext 的位置,即 curr -> 5
  6. 第五次迭代

    • 进入循环,next 指向 curr.next,即 null
    • 链表状态:prev -> 4 -> 3 -> 2 -> 1 -> null, curr -> 5 -> null, next -> null
    • curr.next 指向 prev,即 5next 指向 4
    • 移动 prevcurr 的位置,即 prev -> 5 -> 4 -> 3 -> 2 -> 1
    • 移动 currnext 的位置,即 curr -> null
  7. 迭代结束

    • 循环结束,因为此时 curr 为空,退出循环。
    • prev 指向了反转后的链表头部,即 5
    • 返回 prev,即反转后的链表头部。

通过这个例子,可以清晰地看到每个循环迭代过程中,指针的变化以及链表的状态变化,从而实现了链表的反转。
代码:

class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;ListNode next = null;while (curr != null) {next = curr.next;curr.next = prev;prev = curr;curr = next;}return prev;}

4.递归法:

当使用递归法解决链表反转问题时,主要思路是将原问题分解为一个或多个规模较小的子问题,并利用递归的特性解决这些子问题。具体地,对于链表反转问题,我们可以考虑以下步骤:

  1. 确定递归函数的参数和返回值

    • 参数:当前节点 head,即待反转链表的头节点。
    • 返回值:反转后的链表的头节点。
  2. 确定递归函数的终止条件

    • 当链表为空或者只有一个节点时,直接返回该节点,因为不需要反转。
  3. 确定递归函数的递推关系

    • 首先递归地反转剩余部分链表(即 head.next)。
    • 然后将当前节点 head 的下一个节点的 next 指针指向 head,即将当前节点反转。
    • 最后将当前节点 headnext 指针置为空,避免形成循环。
  4. 返回结果

    • 返回反转后的链表的头节点。

总的来说,递归法的思路是将原问题分解为子问题,然后递归地解决子问题,最终将子问题的解合并起来得到原问题的解。在链表反转问题中,递归法的核心在于将当前节点与剩余部分链表进行连接,并将当前节点反转。

class RecursiveSolution {public ListNode reverseList(ListNode head) {if (head == null || head.next == null) {return head;}ListNode new_head = reverseList(head.next);head.next.next = head;head.next = null;return new_head;}
}

通过不断将链表分成两部分,在最后剩下节点5的时候停止递归,进行返回,返回上一层节点时,以节点4为head节点为例,此时的链表是4->5,头节点是4,将4放在当前链表的后方,即head.next.next=head;,再层层返回,便实现了链表的反转。
20240414

二、leetcode 83.删除排序链表中的重复元素

在这里插入图片描述
这个题比较简单的前提是它是一个事先排序好的链表,因而可以采取相邻元素之间两两对比的情况。如果这个链表是一个乱序的情况,比如1,3,4,1,5就不能用这种两两比较的方法。
分析题目,以1,1,2,3,3,为例,我们有两种方法对该问题进行一个解决。

1.迭代法解决该问题

设置一个头节点curr,比较节点curr与下一个节点的值,如果相同则:curr.next=curr.next.next
将curr节点的下一个节点指向这个curr节点下个节点的下一个节点
如果两者不相同,则将curr往右移动一个节点。

// 迭代法
public class Solution {public ListNode deleteDuplicates(ListNode head) {ListNode curr = head;while (curr != null && curr.next != null) {if (curr.val == curr.next.val) {curr.next = curr.next.next;} else {curr = curr.next;}}return head;}
}

2.采用回归的方法来解决

递归删除排序链表中的重复元素的思路是将问题分解为两部分:首先处理头节点及其重复元素,然后递归处理剩余链表。这种方法的关键在于利用递归处理子链表,并将结果链接到当前节点。详细步骤如下:

递归的基本情况:
递归的终止条件:
如果链表为空(head 为 None)或者链表只有一个节点(head.next 为 None),直接返回 head。
递归调用:
将 head.next 传递给递归函数,将返回的结果赋值给 head.next。
比较当前节点(head)和其下一个节点(head.next)的值:
如果值相同,说明存在重复元素,此时将当前节点的下一个节点指向下一个的下一个节点(即删除 head 的下一个节点),并保持当前节点不变。
如果值不同,说明不存在重复元素,直接返回当前节点。
返回链表头部节点。

(鄙人在学这一段的时候觉得递归返回回来的过程真是让人费解,搞不明白这个语句运行顺序,后来自己在纸上捋了几遍)

public class Solution{
public ListNode deleteDuplication(ListNode head){
if(head==null||head.next==null){
return head;
}
head.next=deleteDuplication(head.next);
if(head.val==head.next.val){
head=head.next
}
return head;
}

首先通过递归函数对链表进行分段,以 1,1,2,3,3,null为例,递归不断深入当head.next=null时输出此时head为第二个3,此时将这个第二个3赋值给head.next,此时的head为第一个3,发现此时head的值与head下一个值相同,令head=head.next,此时就相当于删除了第一个3,返回此时的head值为3,但是整个链表中只有这一个3了。此时的3为这个递归函数输出的值,将它赋值给head.next,说明此时head是2,2与3不相等,输出此时的head为2,接着一直返回上一层,直到head=null。递归完成。
20240415

总结

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

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

相关文章

Ugee手写板Ex08 S在不同软件中的设置

手写笔的结构 功能对应于鼠标的作用笔尖鼠标左键上面第一个键鼠标右键(效果有时候也不完全等同)上面第二个键鼠标中键 以下测试的软件版本 软件版本windows10WPS2024春季16729Office2007SimpleTex0.2.5Ex08 S驱动版本4.2.4.231109 WPS-word ①点击审…

《R语言与农业数据统计分析及建模》学习——创建与访问数据框

1、数据框的概念和特点 数据框是二维的表格形式数据结构,是R语言中最常用的数据结构之一。有如下特点: (1)异质性:各列不同的数据类型 (2)命名索引:每列都有一个名称 (3&…

开源Windows12网页版HTML源码

源码介绍 开源Windows12网页版HTML源码,无需安装就能用的Win12网页版来了Windows12概念版(PoweredbyPowerPoint)后深受启发,于是通过使用HTML、CSS、js等技术做了这样一个模拟板的Windows12系统,并已发布至github进行…

蓝桥杯2024年第十五届省赛真题-小球反弹

以下两个解法感觉都靠谱&#xff0c;并且网上的题解每个人答案都不一样&#xff0c;目前无法判断哪个是正确答案。 方法一&#xff1a;模拟 代码参考博客 #include <iostream> #include <cmath> #include <vector>using namespace std;int main() {const i…

(二十)C++自制植物大战僵尸游戏僵尸进攻控制实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs 文件位置 实现功能的代码文件位置在Class\Scenes\GameScene文件夹中&#xff0c;具体如下图所示。 ZombiesAppearControl.h /* 僵尸出现波数控制 */ class ZombiesAppearControl { public:/***对于进攻的不同波数…

【吊打面试官系列】Java高并发篇 - 如何停止一个正在运行的线程?

大家好&#xff0c;我是锋哥。今天分享关于 【如何停止一个正在运行的线程&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 如何停止一个正在运行的线程&#xff1f; java如何停止一个正在运行的线程? 在Java中&#xff0c;可以使用Thread.stop()方法来停止一…

Android自带模拟器如何获得ROOT权限

如果在模拟器中不能切换到root权限&#xff0c;很可能是镜像使用的不对。 一.选择镜像标准&#xff1a; 1.运行在PC端选X86_64镜像&#xff0c;才能流畅运行 2.不带google api的镜像 二.步骤 在虚拟机管理器中新建AVD&#xff0c;并下载符合要求的镜像文件 三.验证

【MATLAB】App 设计 (入门)

设计APP 主界面 函数方法 定时器 classdef MemoryMonitorAppExample < matlab.apps.AppBase% Properties that correspond to app componentsproperties (Access public)UIFigure matlab.ui.FigureStopButton matlab.ui.control.ButtonStartButton matlab.ui.cont…

大模型ChatGPT里面的一些技术和发展方向

文章目录 如何炼成ChatGPT如何调教ChatGPT如何武装ChatGPT一些大模型的其他方向 这个是基于视频 https://www.bilibili.com/video/BV17t4218761&#xff0c;可以了解一下大模型里面的一些技术和最近的发展&#xff0c;基本都是2022你那以来的发展&#xff0c;比较新。然后本文…

最新版的GPT-4.5-Turbo有多强

OpenAI再次用实力证明了&#xff0c;GPT依然是AI世界最强的玩家&#xff01;在最新的AI基准测试中&#xff0c;OpenAI几天前刚刚发布的GPT-4-Turbo-2024-04-09版本&#xff0c;大幅超越了Claude3 Opus&#xff0c;重新夺回了全球第一的AI王座&#xff1a; 值得一提的是&#xf…

C++ 模板详解——template<class T>

一. 前言 在我们学习C时&#xff0c;常会用到函数重载。而函数重载&#xff0c;通常会需要我们编写较为重复的代码&#xff0c;这就显得臃肿&#xff0c;且效率低下。重载的函数仅仅只是类型不同&#xff0c;代码的复用率比较低&#xff0c;只要有新类型出现时&#xff0c;就需…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑碳市场风险的热电联产虚拟电厂低碳调度》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Java作业6-Java类的基本概念三

编程1 import java.util.*;abstract class Rodent//抽象类 {public abstract String findFood();//抽象方法public abstract String chewFood(); } class Mouse extends Rodent {public String findFood(){ return "大米"; }public String chewFood(){ return "…

IDEA 编码格式设置 UTF-8

IDEA 编码格式设置 UTF-8 1.文件编码设置为UTF-8 Editor > File Encodings 2.编译编码设置为utf-8 Build&#xff0c;Execution&#xff0c;Deployment > Complier > Java Complier 按图中设置&#xff1a;-encoding utf-8

Dynamic Wallpaper for Mac:动态壁纸让桌面更生动

Dynamic Wallpaper for Mac是一款为苹果电脑用户精心设计的动态壁纸软件&#xff0c;它以其丰富的功能和精美的壁纸库&#xff0c;为用户带来了更加生动和个性化的桌面体验。 Dynamic Wallpaper for Mac v17.8中文版下载 这款软件支持多种动态壁纸&#xff0c;用户可以根据自己…

PTA L2-047 锦标赛

题目 解析 把每一场比赛看作满二叉树的一个节点&#xff0c;父节点递归遍历子节点的结果&#xff0c;进行试填。 代码 #include <bits/stdc.h>using i64 long long;struct Node {int win, lose; };void solve() {int k;std::cin >> k;int siz (1 << k);…

【YOLOv8改进[Backbone]】使用MobileNetV3助力YOLOv8网络结构轻量化并助力涨点

目录 一 MobileNetV3 1 面向块搜索的平台感知NAS和NetAdapt 2 反向残差和线性瓶颈 二 使用MobileNetV3助力YOLOv8 1 整体修改 ① 添加MobileNetV3.py文件 ② 修改ultralytics/nn/tasks.py文件 ③ 修改ultralytics/utils/torch_utils.py文件 2 配置文件 3 训练 其他 …

如何查看项目中使用的Qt版本

如何查看项目中使用的Qt版本 1.点击左下角电脑按钮查看Qt版本。 2.点击左侧栏项目按钮查看Qt版本。

apipost、postman等工具上传图片测试flask、fastapi的文件api接口

参考&#xff1a;https://blog.csdn.net/qq_15821487/article/details/119354129 https://www.cnblogs.com/wyxjava/p/16076176.html 选择from-data&#xff0c;下拉选择file上传文件发送即可

MySQL-数据库基础

一、背景与基本使用 首先是登录方式&#xff0c;一般用 mysql -h 127.0.0.1 -P 3306 -u root -p mysql也是一种网络服务。 当然我们在本地登录时可以省去主机ip和端口号。 -h表示我们要登录mysql在哪个ip的主机上&#xff0c; -P表示端口号。 -u表示以谁的身份去登录。…