【leetcode】链表(2)

目录

1. 环形链表

解题思路

2. 环形链表 II

解题思路

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

解题思路

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

解题思路

5. 移除链表元素

解题思路

6. 链表的中间结点

解题思路


1. 环形链表

OJ:环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1

输出:true

解释:链表中有一个环,其尾部连接到第二个节点。

解题思路

快慢指针

快指针走两步,慢指针走一步,如果链表带环,两个最终肯定会在环内相遇;如果链表不带环,快指针肯定会走到链表的末尾

 public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null){
            return false;
        }
        ListNode low = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            low = low.next;
            if(fast == low){
                return true;
            }
        }
        return false;
    }

2. 环形链表 II

OJ:环形链表 II

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1

输出:返回 null

解释:链表中没有环。

解题思路

 

public ListNode detectCycle(ListNode head) {
//        快慢指针相遇时,引入新节点从链表头开始,慢的一定会和新节点在环形第一个节点相遇
        ListNode low = head;
        ListNode fast = head;
        while (fast != null && fast.next != null){
            low = low.next;
            fast = fast.next.next;
            if(fast == low){
                ListNode third = head;
                while (third != low){
                    third = third.next;
                    low = low.next;
                }
                return low;
            }
        }
        return null;
    }

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

OJ:删除排序链表中的重复元素

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

示例 1:

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

示例 2:

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

解题思路

  • 思路1

由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。当cur与cur.next的元素相等时,删除cur.next。下面给出了两种实现方法。

 

public ListNode deleteDuplicates(ListNode head) {      
        if(head == null || head.next == null){
            return head;
        }
//        至少有两个节点
//        头节点val在范围之外

        if (head == null) {
            return head;
        }

        ListNode cur = head;
        while (cur.next != null) {
            if (cur.val == cur.next.val) {
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return head;
    }
public ListNode deleteDuplicates(ListNode head) {
        if(head ==null ||head.next == null){
            return null;
        }
        head = deleteDuplicates(head.next);
        return head.val == head.next.val ? head.next : head;
        
    }

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

OJ:删除排序链表中的重复元素 II

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

示例 1:

输入:head = [1,2,3,3,4,4,5]

输出:[1,2,5]

示例 2:

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

输出:[2,3]

解题思路

    public ListNode deleteDuplicates(ListNode head) {
        // 1.base case
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummyHead = new ListNode(-101);
        dummyHead.next = head;
        ListNode prev = dummyHead;
        ListNode cur = prev.next;
        while (cur != null) {
            ListNode sec = cur.next;
            if (sec == null) {
                break;
            }
            if (cur.val != sec.val) {
                prev = prev.next;
            }else {
                // 此时cur和sec相等
                while (sec != null && cur.val == sec.val) {
                    sec = sec.next;
                }
                // 此时sec一定走到第一个和cur不相等的结点
                // prev .. sec全都是待删除的结点
                prev.next = sec;
            }
            cur = sec;
        }
        return dummyHead.next;
    }
 //递归法
    // 传入一个以head为头节点的链表,就能删除其中所有的重复元素,重复元素一个都不保留
    public ListNode deleteDuplicates(ListNode head) {
        // 1.base case
        if(head == null || head.next == null) {
            return head;
        }
        if(head.val != head.next.val) {
            head.next = deleteDuplicates(head.next);
            return head;
        }else {
            // 头节点就是重复的节点,先处理完头节点的情况
            ListNode newHead = head.next;
            while(newHead != null && newHead.val == head.val) {
                newHead = newHead.next;
            }
            // 此时newHead一定不是待删除的结点,最终整个传入函数,返回更新后的值即可
            return deleteDuplicates(newHead);
        }
    }

5. 移除链表元素

OJ:移除链表元素

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

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6

输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1

输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7

输出:[]

解题思路

(1)先判断头节点元素是否与val相等,相等删除头节点(head = head.next)

(2)判断后面的节点元素是否与val相等,相等删除(prev.next = prev.next.next;);不相等往下继续遍历。直至到链表尾部。

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

        // 有头节点的链表解法
        ListNode dummyHead = new ListNode();
        //与原链表建立联系
        dummyHead.next = head;
        ListNode prev = dummyHead;
        while(prev.next != null){
            if(prev.next.val == val){
                prev.next = prev.next.next;
            }else{
                prev = prev.next;
            }
        }
        return dummyHead.next;
    }
public ListNode removeElements(ListNode head, int vals) {
        if(head == null){
            return null;
        }
        head.next = removeElements(head.next,vals);
        return head.val == vals ? head.next :head;
    }

6. 链表的中间结点

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

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:head = [1,2,3,4,5]

输出:[3,4,5]

解释:链表只有一个中间结点,值为 3 。

示例 2:

输入:head = [1,2,3,4,5,6]

输出:[4,5,6]

解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。

解题思路

  • 思路1

快慢指针,慢指针走一步,快指针走两步,当快指针走到链表最后一个或走到空时,慢指针走到中间节点。

public ListNode middleNode(ListNode head) {
        ListNode fast = head;
        ListNode low = head;
        while (fast!= null && fast.next != null){
            low = low.next;
            fast = fast.next.next;
        }
        return low;
    }
  • 思路2

先求出链表长度,再除以2,就是中间节点的位置了,从链表头遍历到该位置再返回。

    public ListNode middleNode(ListNode head) {
        int length = 0;
        ListNode node = head;
        while(node != null){
            length++;
            node = node.next;
        }
        length = length / 2;
        node = head;
        for(int i =0;i<length;i++){
            node = node.next;
        }
        return node;
    }

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

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

相关文章

第二章 作业(6789B)【编译原理】

第二章 作业【编译原理】前言推荐第二章 作业678911最后前言 以下内容源自《编译原理》 仅供学习交流使用 推荐 无 第二章 作业 6 6.令文法G6为 N→D|ND D→0|1|2|3|4|5|6|7|8|9 (1)G6的语言L(G6)是什么? (2)给出句子0127、34和568的最左推导和最右推导。 &#xff08;…

【开发】后端框架——SpringBoot

title: SpringBoot top: 56 categories: 开发后端框架 tags:开发后端框架SpringBoot abbrlink: 1864766114 date: 2022-03-15 21:49:17 前置知识&#xff1a; Spring Mybatis SpringMVC 学习视频&#xff1a;https://www.bilibili.com/video/BV1PE411i7CV?spm_id_from333.337…

【Linux】进程控制

进程创建fork/vfork1.1.fork函数初识在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。#include <unistd.h> pid_t fork(void); //返回值&#xff1a;自进程中返回0&#xff0c;父进程返回子…

前端实现一个名言生成器

The sand accumulates to form a pagoda✨ 写在前面✨ JS是什么&#xff1f;✨ 名言生成器✨ 页面搭建✨ 功能实现✨ 写在前面 在上周我们通过HTML、CSS实现了一个简单的‘我的相册‘页面的搭建&#xff0c;很多伙伴呢跟我说难道前端就只能做一些页面搭建的工作吗&#xff1f;…

Linux系统编程 - 基础IO(IO操作)

目录 预备知识 复习C文件IO相关操作 printf相关函数 fprintf snprintf 读取文件 系统文件IO操作 open函数 umask()函数 open函数返回值 预备知识 1.你真的理解文件原理和操作了吗&#xff1f;不是语言问题&#xff0c;是系统问题2.是不是只有C/C有文件操作呢&#x…

【Java开发】设计模式 08:组合模式

1 组合模式介绍组合模式是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构&#xff0c;以表示部分-整体的层次结构。组合模式使得客户端可以统一处理单个对象和组合对象&#xff0c;从而简化了客户端代码。在组合模式中&#xff0c;有两种类型的对象&#xff1a;叶子…

【C语言初阶】函数

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;函数是什么&#xff1f;&#x1f337;函数的分类&#x1f33a;库函数&#x1f33a;自定义函数&#x1f337;函数的参数&#x1f337;函数的调用&#x1f337;函数的嵌套调用和链式访问&#x1f33a;嵌套调用&a…

小游戏也要讲信用

当下&#xff0c;小游戏鱼龙混杂&#xff0c;官方为能更好地保护用户、开发者以及平台的权益&#xff0c;近日宣布7月1日起试行小游戏主体信用分机制。 主体信用分是什么呢&#xff1f;简单来说&#xff0c;这是针对小游戏主体下所有小游戏帐号行为&#xff0c;对开发者进行评…

深度学习中的学习率设置技巧与实现详解

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

(五)Tomcat源码阅读:Engine组件分析

一、概述 在阅读源码之前我们需要对各个类的关系有一个清晰的了解&#xff0c;下面就是Engine各个类之间的关系&#xff0c;我们将会按照从上到下的顺序阅读源码。 二、阅读源码 1、Container &#xff08;1&#xff09;注释 Container可以处理请求并给予相应&#xff0c;并…

JavaScript-扫盲

文章目录1. 前言2. 第一个 JavaScript 程序3. javaScript 的基础语法3.1 变量3.2 数据类型3.3 运算符3.4 条件语句3.5 数组3.6 函数3.7 作用域3.8 对象4. WebAPI4.1 DOM 基本概念4.2 常用 DOM API4.3 事件4.4 操作元素4.5 网页版猜数字游戏4.6 留言版1. 前言 提问 java 和 java…

集合之CurrentHashMap 1.7总结

文章目录底层实现构造方法默认的三个参数什么是Unsafe类&#xff1f;它有什么作用&#xff1f;为什么CurrentHashMap 调用Unsafe方法不会报错&#xff1f;我们自己创建的对象调用会报错&#xff1f;CurrentHashMap的key&#xff0c;value可以为null吗&#xff1f;CurrentHashMa…

水风险指数定义及计算:水资源压力等

水风险指数&#xff08;Water risk indicators&#xff09; 水风险指数&#xff08;Water risk indicators&#xff09;是用来评估水资源可持续性和水相关风险的一种工具&#xff0c;可以通过多种指标来衡量。 1.1 水资源压力&#xff08;water stress, WS&#xff09; 定义…

leetcode -- 142. 环形链表 II

&#x1f428;目录&#x1f4dc;1. 题目&#x1f50d;2. 思路&#x1f511;2.1 链表是否带环&#x1f511;2.2 为何能追上&#x1f511;2.3 入口点的确定&#x1f513;3. 代码实现&#x1f4e1;4. 题目链接&#x1f4dc;1. 题目 给定一个链表的头节点 head&#xff0c;返回链表…

自定义类型 (位段、枚举、联合体)

文章目录&#x1f4ec;位段&#x1f50e;1.什么是位段&#x1f50e;2.位段的内存分配&#x1f50e;3.位段的跨平台问题&#x1f4ec;枚举&#x1f50e;1.枚举类型的定义&#x1f50e;2.枚举的优点&#x1f50e;3.枚举的使用&#x1f4ec;联合&#xff08;共用体&#xff09;&am…

C/C++中for语句循环用法及练习

目录 语法 下面是 for 循环的控制流&#xff1a; 实例 基于范围的for循环(C11) 随堂笔记&#xff01; C语言训练-计算1~N之间所有奇数之和 题目描述 输入格式 输出格式 样例输入 样例输出 环形方阵 干货直达 for 循环允许您编写一个执行特定次数的循环的重复控制结构。…

Go语言基础:数组定义及循环遍历

前言 大家好&#xff0c;我是沐风晓月&#xff0c;本文go语言入门-掌握go语言函数收录于《go语言学习专栏》专栏&#xff0c;此专栏带你从零开始学习go语言&#xff0c;持续更新中&#xff0c;欢迎点赞收藏。 &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人…

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方&#xff1a; URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…

RedgateClone启用并行工作流 crack

RedgateClone启用并行工作流 crack RedgateClone允许您轻松创建用于开发和测试场景的数据库的一次性副本。通过使用生产数据库的克隆来降低成本并提高测试和发布的质量。Redgate克隆支持Microsoft SQL Server、Postgres、Oracle和MySQL数据库。 红门克隆的好处 最多可节省99%的…

CentOS从gcc 4.8.5 升级到gcc 8.3.1

gcc -v查看当前gcc版本。 sudo yum install centos-release-scl-rh安装centos-release-scl-rh。 sudo yum install devtoolset-8-build安装devtoolset-8-build。 显示“Complete!”表示安装成功。 sudo yum install devtoolset-8-gdb安装devtoolset-8-gdb。 显示“Comple…