代码随想录算法训练营第4天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交 、142.环形链表II

news2024/11/27 20:23:06

JAVA语言编写

24. 两两交换链表中的节点

谷歌、亚马逊、字节、奥多比、百度

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

img

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

示例 2:

输入:head = []
输出:[]

示例 3:

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

提示:

  • 链表中节点的数目在范围 [0, 100]
  • 0 <= Node.val <= 100

教程:https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

视频:https://www.bilibili.com/video/BV1YT411g7br

方法一:双指针法

思路

24.两两交换链表中的节点1

操作之后的链表:

24.两两交换链表中的节点2

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dumyhead = new ListNode(-1); // 设置一个虚拟头结点
        dumyhead.next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
        ListNode cur = dumyhead;
        ListNode temp; // 临时节点,保存两个节点后面的节点
        ListNode firstnode; // 临时节点,保存两个节点之中的第一个节点
        ListNode secondnode; // 临时节点,保存两个节点之中的第二个节点
        while (cur.next != null && cur.next.next != null) {
            temp = cur.next.next.next;
            firstnode = cur.next;
            secondnode = cur.next.next;
            cur.next = secondnode;       // 步骤一
            secondnode.next = firstnode; // 步骤二
            firstnode.next = temp;      // 步骤三
            cur = firstnode; // cur移动,准备下一轮交换
        }
        return dumyhead.next;
    }
}

19. 删除链表的倒数第 N 个结点

字节跳动、亚马逊、Facebook

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

img

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

示例 2:

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

示例 3:

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

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

**进阶:**你能尝试使用一趟扫描实现吗?

教程:https://programmercarl.com/0019.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9.html

视频:https://www.bilibili.com/video/BV1vW4y1U7Gf

方法一:自己写的

思路:很简单的方法,首先写一个循环遍历head,获得当前val的个数size。根据倒数第n个数、与size及正着数的索引的关系:flag=size-n+1,删除结点。对于特殊情况,head为null,则返回空。若删除是头结点,也就是n=size的时候,直接返回head.next。

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
if (head==null) return null;
        int size=0;
        ListNode cur = head;
        ListNode temp=head;
        ListNode pre = new ListNode(0,temp);
        while(cur!=null){
            cur = cur.next;
            size++;//计算当前ListNode的个数
        }
        if(n==size) return head.next;//如果是删第一个的话,就返回head.next
        
        int flag=0;//记录索引位置
        while(temp!=null){//temp是遍历的
            if(flag==size-n){//size-n是正数的索引前一个
                pre.next=temp.next;//删除操作
            }
            flag++;
            temp=temp.next;
            pre=pre.next;
        }
        return head;
    }
}

160. 相交链表

字节跳动

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null

图示两个链表在节点 c1 开始相交**:**

img

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

示例 1:

img

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

img

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

img

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

提示:

  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 0 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listAlistB 没有交点,intersectVal0
  • 如果 listAlistB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]

**进阶:**你能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案?

教程:https://programmercarl.com/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4.html

方法一:

思路:求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。否则循环退出返回空指针。

复杂度分析

  • 时间复杂度: O ( n A + n B ) O(nA+nB) O(nA+nB),nA是链表A的长度,nB是链表B的长度
  • 空间复杂度: O ( 1 ) O(1) O(1)
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != null) { // 求链表A的长度
            lenA++;
            curA = curA.next;
        }
        while (curB != null) { // 求链表B的长度
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            //1. swap (lenA, lenB);
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            //2. swap (curA, curB);
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap-- > 0) {
            curA = curA.next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != null) {
            if (curA == curB) {
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;
    }

}

142. 环形链表 II

字节跳动、谷歌 Google、Facebook

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

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

不允许修改 链表。

示例 1:

img
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

img
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

img
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

提示:

  • 链表中节点的数目范围在范围 [0, 104]
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

**进阶:**你是否可以使用 O(1) 空间解决此题?

教程:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

视频:https://www.bilibili.com/video/BV1if4y1d7ob/

方法一:

思路:可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {// 有环
                ListNode index1 = fast;
                ListNode index2 = head;
                // 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}

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

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

相关文章

浙大网新:重视AI驱动,就是重视未来发展

【科技明说 &#xff5c; 重磅专题】 对于浙大网新在AI方面的发展情况&#xff0c;我是看到一个消息之后才开始有了关注&#xff0c;之前总感觉浙大网新在AI方面战略雷声大雨点小&#xff0c;然而当我看到这个消息后才发现&#xff0c;浙大网新其实也非常重视AI方面的发展。 …

【微信小程序】WXML的模板语法与WXSS模板样式

&#x1f5a5;️&#x1f5a5;️&#x1f5a5;️ 博主主页&#xff1a; &#x1f449;&#x1f3fb; &#x1f449;&#x1f3fb; &#x1f449;&#x1f3fb; 糖 &#xff0d;O&#xff0d; &#x1f6a9;&#x1f6a9;&#x1f6a9;微信小程序专栏&#xff1a;微信小程序 &…

聚量推客升级啦,加入了外卖cps、话费充值等

“聚量推客”升级啦&#xff0c;加入了生活cps模块&#xff0c;包含美团外卖cps、滴滴打车出行cps、电影票推广、话费充值等cps推广场景&#xff0c;聚量推客不止是app地推拉新和网推拉新平台&#xff0c;更是一个 综合性推广平台&#xff0c;未来会接入越来越多的推广场景&…

OpenCV官方教程中文版 —— Hough 直线变换

OpenCV官方教程中文版 —— Hough 直线变换 前言一、原理二、OpenCV 中的霍夫变换三、Probabilistic Hough Transform 前言 目标 • 理解霍夫变换的概念 • 学习如何在一张图片中检测直线 • 学习函数&#xff1a;cv2.HoughLines()&#xff0c;cv2.HoughLinesP() 一、原理…

基础课13——数据异常处理

数据异常是指数据不符合预期或不符合常识的情况。数据异常可能会导致数据分析结果不准确&#xff0c;甚至是错误&#xff0c;因此在进行数据分析之前需要对数据进行清洗和验证。 常见的数据异常包括缺失值、重复值、异常值等。 缺失值是指数据中存在未知值或未定义的值&#…

Winform 多语言化快速解析替换工具-1分钟一个界面

随着业务的扩展&#xff0c;有的软件有多语言化的需求。那么如果软件已经很多写死的文字内容如何快速进行语言化替换呢&#xff0c;一个一个去改工作量太大。 于是开发了个小工具用来替换现有内容并生成语音包&#xff0c;原理就是采用正则表达式进行匹配控件关键字以及中文进…

使用MLC-LLM将RWKV 3B模型跑在Android手机上

0x0. 前言 这篇文章主要是填一下 MLC-LLM 部署RWKV World系列模型实战&#xff08;3B模型Mac M2解码可达26tokens/s&#xff09; 这里留下来的坑&#xff0c;这篇文章里面介绍了如何使用 MLC-LLM 在A100/Mac M2上部署 RWKV 模型。但是探索在Android端部署一个RWKV对话模型的ap…

宇信科技:强势行业加速融入AIGC,同时做深做细

【科技明说 &#xff5c; 重磅专题】 大家可能没有想到&#xff0c;一向对外低调行事的宇信科技&#xff0c;在AIGC方面2023年就已经训练出了适配金融场景的垂直模型&#xff0c;并应用到了各产品线上&#xff0c;同时结合通用大模型预研了宇信金融系统编程大模型。宇信金融系…

IOC课程整理-15 Spring 类型转换

1. Spring 类型转换的实现 2. 使用场景 3. 基于 JavaBeans 接口的类型转换 4. Spring 內建 PropertyEditor 扩展 5. 自定义 PropertyEditor 扩展 6. Spring PropertyEditor 的设计缺陷 7. Spring 3 通用类型转换接口 8. Spring 內建类型转换器 9. Converter 接口的局限性 10. G…

Azure - 机器学习:使用 Apache Spark 进行交互式数据整理

目录 本文内容先决条件使用 Apache Spark 进行交互式数据整理Azure 机器学习笔记本中的无服务器 Spark 计算从 Azure Data Lake Storage (ADLS) Gen 2 导入和整理数据从 Azure Blob 存储导入和处理数据从 Azure 机器学习数据存储导入和整理数据 关注TechLead&#xff0c;分享AI…

深入理解Linux网络笔记(五):深度理解本机网络IO

本文为《深入理解Linux网络》学习笔记&#xff0c;使用的Linux源码版本是3.10&#xff0c;网卡驱动默认采用的都是Intel的igb网卡驱动 Linux源码在线阅读&#xff1a;https://elixir.bootlin.com/linux/v3.10/source 4、深度理解本机网络IO 1&#xff09;、跨机网络通信过程 …

快速排序——及其改进

hoare版本&#xff08;原始版本&#xff09;&#xff1a; 思想&#xff1a;树的遍历思想&#xff0c;先把数组第一个数作为KEY,然后left从左到右&#xff0c;right从右到左一起走&#xff0c;当left找到比key大的值时停下来&#xff0c;当right找到比key小的值时停下来&#xf…

通讯网关软件030——利用CommGate X2Modbus实现Modbus RTU访问Mysql服务器

本文介绍利用CommGate X2Modbus实现Modbus RTU访问Mysql数据库。CommGate X2MODBUS是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现上位机通过Modbus RTU来获取Mysql数据库的数据。 【解…

IOC课程整理-16

1. Java 泛型基础 Java中的泛型擦除&#xff08;Type Erasure&#xff09;是Java编译器为了兼容之前的非泛型代码而采用的一种机制。在编译过程中&#xff0c;Java编译器会将泛型类型转换为原始类型&#xff0c;并在必要时插入强制类型转换。 泛型擦除有以下几个主要特点&…

深度学习_1 介绍;安装环境

深度学习 学习自李沐老师的课程。笔记主要以总结老师所讲解的内容以及我个人的想法为主&#xff0c;侵删&#xff01; 课程链接&#xff1a;课程安排 - 动手学深度学习课程 (d2l.ai) 介绍 AI地图&#xff1a; 我们以前写的非 AI 类程序基本都是人自己去想会遇到什么样的问题…

【PyQt学习篇 · ③】:QObject - 神奇的对象管理工具

文章目录 QObject类型判定常用的API应用场景&#xff1a;过滤筛选控件 QObject定时器常用API应用场景 QObject类型判定 常用的API isWidgetType()方法&#xff1a; 使用方式&#xff1a;obj.isWidgetType()作用&#xff1a;判断一个对象是否为QWidget及其子类的实例。QWidget…

4.5 final修饰符

在Java中&#xff0c;final修饰符可以修饰类、属性和方法&#xff0c;final有“最终”、“不可更改”的含义&#xff0c;所以在使用final关键字时需要注意以下几点&#xff1a; 使用final修饰类&#xff0c;则该类就为最终类&#xff0c;最终类不能被继承。 使用final修饰方法…

C++----模板进阶

文章目录 非类型模板参数STL知识补充 类模板的特化函数模板特化类模板特化偏特化 模板的分离编译模板总结 非类型模板参数 模板参数分为类型形参与非类型形参。 类型形参&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参…

Vue性能优化:加速你的应用

目录 1. 使用虚拟DOM 2. 合理使用计算属性和侦听器 3. 懒加载组件 4. 合理使用v-if和v-show 5. 使用Key管理列表渲染 6. 避免不必要的Watcher 7. 缓存响应式数据 8. 使用异步组件 9. 使用Webpack进行代码优化 10. 监控性能并进行优化 Vue.js是一款流行的JavaScript框…

东软集团:看似低调,却有了19年的AI坚持

【科技明说 &#xff5c; 重磅专题】 在AI领域的专注与研究&#xff0c;东软集团是一个低调的存在。 可能很多人不太了解东软集团对于AI的专心与专注以及专业。三专可以简单概括东软集团的AI雄心壮志。 专注在于&#xff0c;早在2004年&#xff0c;东软就开始启动人工智能技…