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

news2024/9/25 11:20:31

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

力扣题目链接(opens new window)

解析:

基础题,主要是要把握边界条件:由题可得,交换的节点两两一组,每交换完成一对,问题规模减2,也就是只剩一个或不剩节点时交换便结束

在这里,我们引入一个虚拟头节点,这样所有的交换操作便得到统一。

每一对节点交换一次,不开辟额外空间,因此时间复杂度O(n),空间复杂度O(1)

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummy_head = new ListNode(-1, head); //虚拟头节点
        if(head == nullptr || head->next == nullptr) return head; //边界条件先判断
        ListNode* cur2 = head->next;
        ListNode* cur1 = head;
        ListNode* pre = dummy_head; //两个需要交换的节点,及前节点,共三个节点
        while(cur1 && cur2){
            cur1->next = cur2->next;
            cur2->next = cur1;
            pre->next = cur2;

            pre = cur1;
            if(cur1->next && cur1->next->next){ //若只剩1个或不剩 则退出交换
                cur2 = cur1->next->next;
                cur1 = cur1->next;
            }
            else {
                break;
            }
        }
        head = dummy_head->next; //头节点还原
        delete dummy_head;
        return head;
    }
};

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

力扣题目链接

解析:

本题以普通办法处理的话就是先遍历一遍,确定链表长度,再遍历一遍,实施删除。虽然不会到O(n^2)的复杂度,仍为线性,但是连续遍历两遍不免让人觉得不快。

因此此类问题,同样可以借鉴双指针法,一前一后不回溯的遍历链表,让前后指针距离保持 n 的距离,那么当后指针到达链表尾的时候,我们自然而然可以靠前指针确定删除位置,且该算法只需一遍遍历。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode* dummy_head = new ListNode(-1,head);
            ListNode* p = dummy_head;
            ListNode* q = dummy_head;
            int kick_off = 0;
            while(kick_off < n && p->next){ //先让p指针先行,确定q指针何时行动
                p = p->next;
                kick_off++;
            }
            while(p->next){ //同步行动,直至p指针到最后一个节点,q指针离p n 个位置远
                p = p->next;
                q = q->next;
            }
            ListNode *tmp = q->next;
            q->next = q->next->next; //实施删除

            if(dummy_head->next){ //判断一下是否链表就一个节点,且已被删除
                head = dummy_head->next;
            }
            else{
                head = nullptr;
            }
            delete tmp; // 回收要删除的节点
            delete dummy_head; //回收虚拟头
            return head;
    }
};

160.链表相交

力扣题目链接(opens new window)

解析:

这道题需要巧妙利用到一个思维,也就是链表尾对齐的思维。

如图:若两个链表有相交点,则该交点后的节点均为同一个节点,也就是它们是尾部相等的。所以如果我们能找到长表较之于短表表头的中间位置(等长的位置),然后顺序同步一对一对节点的比较是否相等,便能找到第一个相同的节点,且时间复杂度能控制在O(m+n)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* qq = headA;
        int lenA = 1;
        int lenB = 1;
        ListNode* pp = headB;
        while(qq->next){ //计算A的长度
            qq = qq->next;
            lenA++;
        }
        while(pp->next){ //计算B的长度
            pp = pp->next;
            lenB++;
        }
        ListNode* q = headA;
        ListNode* p = headB;
        if(lenA < lenB){ // 让q指向较长的链表的表头
            int tmp = lenA;
            ListNode* _tmp = q; 
            lenA = lenB;
            lenB = tmp;
            q = p;
            p = _tmp;
        }
        int offset = lenA - lenB;
        while(offset > 0 ){ //想象两个不等长的链表,由末尾对齐,将较长的链表的指针遍历到与较短的链表表头节点对齐
            q = q->next;
            offset--;
        }
        while(q != p && q){ //开始判等
            q = q->next;
            p = p->next;
        }
        return q;
    }
};

142.环形链表II

力扣题目链接

解析:

该题涉及到一个数学推理,详情见卡哥:代码随想录

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* p = head;
        ListNode* q = head;
        while( q && q->next){
            p = p->next;
            q = q->next->next;
            if(p == q){
                ListNode* pp = head;
                ListNode* qq = q;
                while(pp != qq){
                    pp = pp->next;
                    qq = qq->next;
                }
                return qq;
            }
        }
        return NULL;
    }
};

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

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

相关文章

ArcGIS基础实验操作100例--实验28地形图配准

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验28 地形图配准 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&#x…

python中类的使用详解

目录 一.类的定义和使用方法 成员变量和成员方法 成员方法的定义语法和self关键字 小结 二.类和对象 小结 三.属性&#xff08;成员变量&#xff09;的赋值 构造方法&#xff1a;_ _init_ _() 小结 一.类的定义和使用方法 可以使用类去封装属性&#xff0c;并基于类创建…

一文弄懂Pytorch的DataLoader,Dataset,Sampler之间的关系

很多文章都是从DatasetDatasetDataset等对象自下网上进行介绍的&#xff0c;但是对于初学者而言&#xff0c;其实这并不好理解&#xff0c;因为有时候&#xff0c;会不自觉的陷入到一些细枝末节中去&#xff0c;而不能把握重点&#xff0c;所以本文将自上而下的对PytorchPytorc…

HCIP第四天

HCIP实验配置一&#xff0c;实验要求二&#xff0c;172.16.0.0/16地址的划分三&#xff0c;搭建拓扑图四&#xff0c;配置IP地址和环回地址五&#xff0c;宣告并配置缺省路由下放&#xff0c;使用NAT技术六&#xff0c;R5中心站点配置隧道和静态IP七&#xff0c;R6分支站点的配…

canvas在小程序里写小游戏

最近接了个小需求需要写个小游戏&#xff0c;由简单的帧动画加上碰撞相关的处理&#xff0c;组成。具体页面信息如下图 具体的游戏步骤&#xff0c;是通过长按按钮蓄力&#xff0c;松开时卡通人物跳起&#xff0c;卡通人物跳起碰撞到上面的元宝等元素的得分&#xff0c;这里我们…

笔试题之编写SQL分析门店销售情况

销售员、客户、产品 文章目录前言一、SQL题目二、解答方法&#xff08;一&#xff09;建表插入测试数据&#xff08;二&#xff09;第一题解答&#xff08;三&#xff09;第二题解答&#xff08;四&#xff09;第三题解答总结前言 分享本人遇到的笔试真题与解法&#xff0c;并…

MATLAB算法实战应用案例精讲-【人工智能】语义分割(附实战应用案例及代码)

前言 语义分割是一种典型的计算机视觉问题,其涉及将一些原始数据(例如,平面图像)作为输入并将它们转换为具有突出显示的感兴趣区域的掩模。许多人使用术语全像素语义分割(full-pixel semantic segmentation),其中图像中的每个像素根据其所属的感兴趣对象被分配类别ID。…

[ XSS-labs通关宝典 ] xss-labs 通关宝典之 less1 - less5

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

前端常见问题汇总(十)

一、HTTP1.0和HTTP2.0的区别 http1.0&#xff1a;每次请求都需要重新建立tcp连接&#xff0c;请求完后立即断开与服务器连接&#xff0c;这很大程度造成了性能上的缺陷&#xff0c;http1.0被抱怨最多的就是连接无法复用。 http1.1&#xff1a;引入了长连接&#xff08;keep-al…

麒麟系统虚拟机安装教程

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 1.首先得安装VM Ware软件。 2.打开VM Ware&#xff0c;点击“文件”->“新建虚拟机”。 3.进入新建虚拟机向导&#xff0c;点击下一步。如下图&…

API管理神器:Apifox

前言 代码未动&#xff0c;文档先行 其实大家都知道 API 文档先行的重要性&#xff0c;但是在实践过程中往往会遇到很多困难。 程序员最讨厌的两件事&#xff1a;1. 写文档&#xff0c;2. 别人不写文档。大多数开发人员不愿意写 API 文档的原因是写文档短期收益远低于付出的…

2023—静待“雨中的海棠”发芽

2023—静待“雨中的海棠”发芽认真负责、全身心的投入工作减少抱怨勤思考、多总结—>高效工作保持7*24小时在线全身心BKGWY坚持不懈多运动骑车车、练哑铃、慢跑多看书看自己喜欢的书环青海湖准备环青海湖的攻略身体上的准备内心信念的支撑最后就静待“雨中的海棠”发芽吧&am…

kali - 扫描

数据来源 Whatweb WhateWhatweb是一个基于Ruby语言的开源网站指纹识别软件&#xff0c;正如它的名字一样,&#xff0c;whate能够识别各种关于网站的详细信息&#xff0c;包括&#xff1a;CMS类型、博客平台、中间件、web框架模块、网站服务器、脚本类型、 Javascript库、lP、 …

Apollo 配置中心

Apollo 配置中心目录概述需求&#xff1a;设计思路实现思路分析1.Apollo 配置中心2.Client端配置中心3.爬虫调度器5.Server端配置中心参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardne…

(免费分享)基于jsp,ssm甜点网站

开发工具&#xff1a;eclipse&#xff0c;jdk1.8 数据库&#xff1a;mysql5.7&#xff0c;Tomcat8.0 package com.softeem.controller;import java.util.HashMap; import java.util.Map;import javax.annotation.Resource;import org.springframework.stereotype.Controller; …

labelImag安装及使用教程

在做目标检测任务时&#xff0c;需要进行标注&#xff0c;选择了LabelImg作为标注工具&#xff0c;下面是安装及使用过程。 我们使用Anconda的虚拟环境进行安装&#xff0c;激活环境后&#xff0c;执行&#xff1a; pip install labelimg -i https://pypi.tuna.tsinghua.edu.c…

WebSocket 协议详述( java在线聊天室_上篇)

文章目录1、 WebSocket 协议1.1、 何为WebSocket&#xff1f;1.2、 websocket 和 http&#xff08;应用层的俩个协议&#xff09;1.3、 websocket协议的具体过程1.4、websocket好处2、 WebSocket实现2.1、 客户端实现2.1.1、 websocket对象2.1.2、 websocket事件2.1.3、 websoc…

【linux】linux中vim/vi (linux基本开发工具)

本期主题&#xff1a;linux中vim/vi的使用和介绍。博客主页&#xff1a;小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐 目录 &#x1f341;vim键盘图 &#x1f341;vim基本概念 &#x1f341;vim的基本操作 &#x1…

Python使用库(二)

Python使用库&#xff08;二&#xff09; 第三方库 认识第三方库 第三方库就是别人已经实现好了的库, 我们可以拿过来直接使用. 虽然标准库已经很强大了, 但是终究是有限的. 而第三方库可以视为是集合了全世界 Python 程序猿的智慧, 可以说是几乎无穷无尽. 问题来了, 当我们…

Linux驱动入门-最简单字符设备驱动(基于pc ubuntu)

一.字符设备驱动概念 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、 IIC、 SPI&#xff0c;LCD 等等都是字符设备&#xff0…