算法训练营Day3(链表)

语言

采用的Java语言,一些分析也是用于Java,请注意。

理论基础

对于链表我之前学的蛮多的,说基础的话,基本上就是说链表在内存上的不连续性

以及要和数组对比,数组知道下表之后,可以直接O(1)级别的查看,修改,而删除、新增不方便

而链表恰恰相反,修改、删除,移动指针就好了,而查看的话需要一个一个遍历

对于Java中的Arraylist和LinkedList那个性能高的时候,LinkedList发明者都说,链表虽然删除容易,但是要删除的前提也是要遍历找到哪个元素,因此在项目中还是基本上使用ArrayList

上面是我对链表的理解,

这里再说下对做题的理解,“一瓶酒、一包烟,一道链表刷一天”,链表题虽然不难,但是很考验编程能力,需要做的就是充分利用虚拟头节点和掌握几个链表的核心基础,如反转链表,移除链表等技巧,这些基本上要背会,因为这些是做某些链表题的基础。

另外,java的小伙伴还要学习一下jvm中的内存可达性算法,GC ROOT的原理,对于链表在内存中如何运行很有帮助,这个会了才方便理解链表题。

 203.移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

不适用虚拟头节点

值得注意的是:while循环为什么多了一个cur!=null

当你使用一个指针(对象引用)的时候  需要确保它是非空的  这里如果用 cur 指向的是 head  无法保证 head 是非空的 所以要对 cur 本身进行判断往后走  如果用 pre 指向 dummy  dummy是自己new的对象  可以确保它是非空的 所以用 pre.next 判断下一个节点

这也是为什么使用dummy节点的时候,while循环里可以省略掉cur!=null

有时候方便理解,我喜欢把cur写成pre。

public ListNode removeElements(ListNode head, int val) {
        while(head!=null && head.val==val){
            head=head.next;
        }

        //2
        //1 2 3 4
        ListNode cur = head;
        while (cur!=null && cur.next!=null){
            if(cur.next.val == val){
                cur.next = cur.next.next;
            }else {
                cur = cur.next;
            }
        }
        return head;
    }

使用虚拟头节点

public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(-1,head);
        //2
        //1 2 3 4
        ListNode pre = dummy;
        while (pre.next!=null){
            if(pre.next.val==val){
                pre.next = pre.next.next;
            }else {
                pre=pre.next;
            }
        }
        return dummy.next;
    }

 707.设计链表

这道题就是考研链表的基本操作,需要注意几个点

1、头节点的巧用

2、更新、删除的时候需要找到n节点的上一个节点,也就是cur指针的next是要找的节点

3、判断是否符合要求的时候,可以用极限值来判断,比如第0个节点

class ListNode{
    int val;
    ListNode next;
    public ListNode(){

    }
    public ListNode(int val){
        this.val = val;
    }

    public ListNode(int val,ListNode next){
        this.val = val;
        this.next = next;
    }
}
public class MyLinkedList {
    /**
     * 链表个数
     */
    int size;
    /**
     * 虚拟头节点
     */
    ListNode dummy;
    public MyLinkedList() {
        size = 0;
        dummy = new ListNode(0);
    }

    public int get(int index) {
        //判断index是否有效
        if(index<0 || index>=size){
            return -1;
        }
        //注意这里是获取节点,因此不需要找到上一个节点,索引cur是dummy.next,
        //上一个节点的话,cur = dummy就可以了
        //因为=dummy的时候,cur正好是第0个节点的上一个
        ListNode cur = dummy.next;
        while(index-->0){
            cur = cur.next;
        }
        return cur.val;
    }

    public void addAtHead(int val) {
        ListNode newHead = new ListNode(val);
        newHead.next = dummy.next;
        dummy.next = newHead;
        size++;
    }

    public void addAtTail(int val) {
        ListNode cur = dummy;
        while(cur.next.next!=null){
            cur = cur.next;
        }
        ListNode newListNode = new ListNode(val);
        newListNode.next = null;
        cur.next = newListNode;
        size++;
    }

    public void addAtIndex(int index, int val) {
        ListNode cur = dummy;
        while(index-->0){
            cur = cur.next;
        }
        ListNode newListNode = new ListNode(val);
        newListNode.next = cur.next;
        cur.next = newListNode;
        size++;
    }

    public void deleteAtIndex(int index) {
        ListNode cur = dummy;
        while(index-->0){
            cur= cur.next;
        }
        cur.next = cur.next.next;
        size--;
    }
}

206.反转链表

206. 反转链表 - 力扣(LeetCode)

双指针解法

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        while(cur!=null){
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

递归解法

class Solution {
     public ListNode reverseList(ListNode head) {
        return reverse(head,null);
    }
    public ListNode reverse(ListNode cur,ListNode pre){
        //递归终止条件
        if(cur==null){
            return pre;
        }
        ListNode temp = cur.next;
        cur.next = pre;
        return reverse(temp,cur);
    }
}

总结

对于203题,不使用虚拟头节点的时候,需要保证cur!=null&&cur.next!=null

这个因为操作节点之前,需要保证操作的节点不为null,如果这个head为null,首先

第一个while循环直接不成立,直接往下走

第二个循环,常规的理解就是cur.next!=null,一个一个判断,但是没用虚拟节点,这个head为null的时候直接操作head.next会直接报错,尾音head本身就是null了,前面加一个cur!=null,因为是&&

cur==null的时候,会直接停止村换,因此&&后面的cur.next不为null

当使用虚拟头节点的时候,因为dummy是我们new出来的,可以保证他是不为null的,正常,

cur指向dummy,while(dummy.next!=null)就可以顺利进行了。dummy后面的head为null

直接结束循环,也不会报错,所以分析需不需要加cur!=null就是注意下是否能保证操作的时候不报空指针异常

对于这个问题,在707题也有一些这样的问题

我给出的代码时运行不了的,我尽力了哈,hah

但是这里的分析是没错的,看看这里的解释

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

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

相关文章

JM中ref_pic_list_modification bug记录

问题描述 今天在用JM对YUV420p编码时,发现编出的码流用ffplay播放花屏,报如下错误: JM的版本时19.1,没有使能B帧,PicOrderCntType设置为2,其它都是encoder.cfg中的默认配置。我用一些码流分析工具播放H264码流正常,用一些播放器播放也都存在花屏,不过大多数播放器都是…

【扩散模型】ControlNet从原理到实战

ControlNet从原理到实战 ControlNet原理ControlNet应用于大型预训练扩散模型ControlNet训练过程ControlNet示例1 ControlNet与Canny Edge2. ControlNet与Depth3. ControlNet与M-LSD Lines4. ControlNet与HED Boundary ControlNet实战Canny Edge实战Open Pose 小结参考资料 Cont…

如何使用ArcGIS Pro制作类似CAD的尺寸注记

经常使用CAD制图的朋友应该比较熟悉CAD内的尺寸标注&#xff0c;这样的标注看起来直观且简洁&#xff0c;那么在ArcGIS Pro内能不能制作这样尺寸注记呢&#xff0c;答案是肯定的&#xff0c;这里为大家介绍一下制作的方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所…

『亚马逊云科技产品测评』活动征文|基于亚马逊云EC2搭建PG开源数据库

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 亚马逊EC2云服务器&#xff08;Elastic Compute Cloud&#xff09;是亚马…

动态设置当前按钮是否可以点击

当审核状态为通过时不可以点击审核按钮 <vxe-columnfixed"right"align"center"width"100"title"操作"><template slot-scope"scope"><el-button v-if"hasPermission(basic:archivalInfo:edit)":di…

资源三号5米全国数字高程模型DEM

简介 近些年来&#xff0c;国产高分辨率遥感卫星的发展突飞猛进&#xff0c;天绘系列卫星、资源三号卫星、高分一号、二号卫星以不断提高的影像空间分辨率、逐步增强的影像获取能力、较好的影像现势性等特点逐步打破了国外商业卫星的主导地位&#xff0c;开始广泛服务于各…

【webpack】应用篇

基础应用 代码分离常用的代码分离方法方法一&#xff1a;配置入口节点方法二&#xff1a;防止重复方法三&#xff1a;动态导入 缓存原因解决思路 缓存第三方库原因解决思路 将所有js文件单独存放文件夹拆分开发环境和生产环境配置公共路径环境变量和区分环境代码压缩 拆分配置文…

【React】路由的基础使用

react-router-dom6的基础使用 1、安装依赖 npm i react-router-dom默认安装最新版本的 2、在src/router/index.js import { createBrowserRouter } from "react-router-dom"/* createBrowserRouter&#xff1a;[/home]--h5路由createHashRouter&#xff1a;[/#/ho…

LAMP部署

目录 一、安装apache 二、配置mysql 三、安装php 四、搭建论坛 4、安装另一个网站 一、安装apache 1.关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下 systemctl stop firewalld systemctl disable firewalld setenforce 0 httpd-2.4.29.tar.gz apr-1.6.2.t…

vue3-vite前端快速入门教程 vue-element-admin

Vue3快速入门学习 初始化项目 # 创建项目 npm create vitelatest my-vue-app -- --template vue # 安装依赖 npm i # 运行 npm run dev 模板语法 文本插值​ 最基本的数据绑定形式是文本插值&#xff0c;它使用的是“Mustache”语法 (即双大括号)&#xff1a; <span&g…

408——知识点大杂烩

在完成专业课的一轮复习以及历年真题的学习后&#xff0c;发现选择题甚至个别大题的考点就单纯考对概念的理解&#xff0c;会就是会&#xff0c;不会想到脑壳疼都做不出来&#xff0c;而408的知识点主打一个多杂&#xff0c;所以过来整理一下笔记。本文的知识点主要是在我做题过…

[FPGA 学习记录] 数码管动态显示

数码管动态显示 文章目录 1 理论学习1.1 数码管动态扫描显示原理 2 实战演练2.1 实验目标2.2 程序设计2.2.1 框图绘制2.2.2 数据生成模块 data_gen2.2.2.1 波形绘制2.2.2.2 代码编写2.2.2.3 代码编译2.2.2.4 逻辑仿真2.2.2.4.1 仿真代码编写2.2.2.4.2 仿真代码编译2.2.2.4.3 波…

玩转Sass:掌握数据类型!

当我们在进行前端开发的时候&#xff0c;有时候需要使用一些不同的数据类型来处理样式&#xff0c;Sass 提供的这些数据类型可以帮助我们更高效地进行样式开发&#xff0c;本篇文章将为您详细介绍 Sass 中的数据类型。 布尔类型 在 Sass 中&#xff0c;布尔数据类型可以表示逻…

Bootstrap V5框架本地引用矢量图标库

文件下载&#xff1a; 使用官方的Github下载地址&#xff1a;Release v1.11.2 twbs/icons GitHub 文件引用&#xff1a; 解压下载zip文件 找到font文件中 引用css和woff文件即可 将文件font文件夹和bootstrap-icons.min.css或者bootstrap-icons.css引用到项目中即可&…

十五届蓝桥杯分享会(一)

注&#xff1a;省赛4月&#xff0c;决赛6月 一、蓝桥杯整体介绍 1.十四届蓝桥杯软件电子赛参赛人数&#xff1a;C 8w&#xff0c;java/python 2w&#xff0c;web 4k&#xff0c;单片机 1.8w&#xff0c;嵌入式/EDA5k&#xff0c;物联网 300 1.1设计类参赛人数&#xff1a;平…

c语言词法分析器

词法分析器&#xff08;也称为词法解析器或词法扫描器&#xff09;是编译器的一个组成部分&#xff0c;它的任务是将输入的源代码&#xff08;字符流&#xff09;分解成称为“标记”的序列&#xff0c;其中每个标记对应于源代码中的一个单词或符号。 以下是一个简单的C语言词法…

用Rust刷LeetCode之66 加一

66. 加一[1] 难度: 简单 func plusOne(digits []int) []int { length : len(digits) // 从最低位开始遍历&#xff0c;逐位加一 for i : length - 1; i > 0; i-- { if digits[i] < 9 { digits[i] return digits } d…

【Linux】已安装 powerlevel10k,报错 command not found: p10k

问题描述 在配置 zsh 时&#xff0c;已经安装了 powerlevel10k&#xff0c;但是当尝试启动 Powerlevel10k 配置向导时&#xff0c;出现了以下错误&#xff1a; p10k configure zsh: command not found: p10k原因分析 出现这个错误的原因是因为 zsh 终端还没有加载最新的配置…

SL1581降压恒压 耐压4V-30V降压5V 2A电流 外围简单,四个元器件

SL1581是一款专为降压恒压应用而设计的芯片&#xff0c;具有耐压4V-30V、降压5V、2A电流输出等特点&#xff0c;外围电路简单&#xff0c;仅需四个元器件。 一、芯片介绍 SL1581是一款专为降压恒压应用而设计的芯片&#xff0c;它采用先进的PWM控制技术&#xff0c;具有高效率、…

KubeSphere Marketpalce 上新!Databend Playground 助力快速启动数据分析环境

12 月 5 日&#xff0c;Databend Labs 旗下 Databend Playground&#xff08;社区尝鲜版&#xff09;成功上架青云科技旗下 KubeSphere Marketplace 云原生应用扩展市场&#xff0c;为用户提供一个快速学习和验证 Databend 解决方案的实验环境。 关于 Databend Playground Dat…