面试常考算法(1):反转链表、局部反转链表(包含误区分析)

news2024/11/24 7:56:24

BM1 反转链表

  给定一个单链表的头结点pHead(该头节点是有值的,,$ 长度为n,反转该链表后,返回新链表的表头。
  数据范围: 0 ≤ n ≤ 1000 0 \leq n \leq 1000 0n1000
  要求: 空间复杂度 O ( 1 ) O(1) O(1) ,时间复杂度 O ( n ) O(n) O(n)
  如当输入链表 { 1 , 2 , 3 } \{1,2,3\} {1,2,3} 时,经反转后,原链表变为 { 3 , 2 , 1 } \{3,2,1\} {3,2,1} ,所以对应的输出为 { 3 , 2 , 1 } \{3,2,1\} {3,2,1}

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
		//考虑空链表
		if (pHead==NULL){return NULL;};
		//反转就是从头开始,依次将*next指向改变
		ListNode *pre = NULL;  // cur的前一个结点,Node中没有,需要额外记录
		ListNode *cur = pHead;
		while(!cur==NULL){  // 对cur指针进行换向
			ListNode *temp = cur->next;
			cur->next = pre;
			// 更新cur和pre
			pre = cur;
			cur = temp;
		}
		return pre;
    }
};

BM2 链表内指定区间反转

  将一个节点数为 size 链表 m m m 位置到 n \mathrm{n} n 位置之间的区间反转,要求时间宴杂度 O ( n ) O(n) O(n) ,空间复杂度 O ( 1 ) O(1) O(1)
例如:
给出的链表为 1 → 2 → 3 → 4 → 5 → N U L L , m = 2 , n = 4 1 \rightarrow 2 \rightarrow 3 \rightarrow 4 \rightarrow 5 \rightarrow N U L L, m=2, n=4 12345NULL,m=2,n=4,
返回 1 → 4 → 3 → 2 → 5 → N U L L 1 \rightarrow 4 \rightarrow 3 \rightarrow 2 \rightarrow 5 \rightarrow N U L L 14325NULL.
数据范围: 链表长度 0 < s i z e ≤ 1000 , 0 < m ≤ n ≤ s i z e 0<s i z e \leq 1000 , 0<m \leq n \leq s i z e 0<size10000<mnsize , 链 表 中 每 个 节 点 的 值 满 足 ∣ v a l ∣ ≤ 1000 |v a l| \leq 1000 val1000
  要求: 时间是杂度 O ( n ) O(n) O(n) ,空间宴杂度 O ( n ) O(n) O(n)
  进阶:时间复杂度 O ( n ) O(n) O(n) ,空间复杂度 O ( 1 ) O(1) O(1)

答案:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        // 如果i=0,相当于head被修改,所以不能直接返回head
        ListNode* vHead = new ListNode(-1);
        vHead->next = head;
        // 找到对应的局部完成反转链表
        ListNode* lHead = head;
        ListNode* pre = vHead;
        for(int i =0;i<m-1;i++){ // 注意寻找第m个结点只需要m-1次next
            pre = lHead;
            lHead = lHead->next;
        }
        // 反转链表,注意不能仅仅只进行cur的变向,得用结点交换的思路
        ListNode* cur = lHead;
        for(int i =m;i<n;i++){
            ListNode* temp = cur->next; //暂存cur下一结点位置
            cur->next = temp->next; //保证尾部和原链表剩余部分链接
            temp->next = pre->next; //对下一结点变向
            pre->next = temp; //保证头和
        }

        return vHead->next;
    }
};

注意和BM1 的区别在于,局部反转时,如果还是采用仅cur指针变向,就会造成局部成环,并且局部反转的尾部结点,没有把next和原有链表相连。
错误示范:

`/**
	 * struct ListNode {
	 *	int val;
	 *	struct ListNode *next;
	 * };
	 */
	class Solution {
	public:
	    /**
	     * 
	     * @param head ListNode类 
	     * @param m int整型 
	     * @param n int整型 
	     * @return ListNode类
	     */
	    ListNode* reverseBetween(ListNode* head, int m, int n) {
	        // 如果i=0,相当于head被修改,所以不能直接返回head
	        ListNode* vHead = new ListNode(-1);
	        vHead->next = head;
	        // 找到对应的局部完成反转链表
	        ListNode* lHead = head;
	        ListNode* pre = vHead;
	        for(int i =0;i<m-1;i++){ // 注意寻找第m个结点只需要m-1次next
	            pre = lHead;
	            lHead = lHead->next;
	        }
	        // 反转链表
	        ListNode* cur = lHead;
	        for(int i =m;i<n;i++){
	            // 将cur的指针变向
	            ListNode* temp = cur->next;
	            cur ->next=pre;
	            // 更新pre和cur
	            pre = cur;
	            cur = temp;
	        }
	
	        return vHead->next;
	    }
	};`

导致结果:
在这里插入图片描述
注意就算考虑了尾部相连,但如果还是按照BM1的思路更新pre和cur,然后将局部依次变向,会导致顾尾不顾头
在这里插入图片描述

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

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

相关文章

QT QHorizontalSpacer弹簧控件

本文详细的介绍了QHorizontalSpacer控件的各种操作&#xff0c;例如&#xff1a;新建界面、控件布局、隐藏控件、设置宽高、添加布局、其它参数、.h源文件、cpp源文件、其它文章等等操作。 实际开发中&#xff0c;一个界面上可能包含十几个控件&#xff0c;手动调整它们的位置既…

最优化简明版(上)

引言 本文简单地介绍一些凸优化(Convex Optimization)的基础知识&#xff0c;可能不会有很多证明推导&#xff0c;目的是能快速应用到机器学习问题上。 凸集 直线与线段 设 x 1 ≠ x 2 x_1 \neq x_2 x1​x2​为 R n \Bbb R^n Rn空间中的两个点&#xff0c;那么具有下列形…

基于 log4j2 插件实现统一日志脱敏,性能远超正则替换

前言 金融用户敏感数据如何优雅地实现脱敏&#xff1f; 日志脱敏之后&#xff0c;无法根据信息快速定位怎么办&#xff1f; 经过了这两篇文章之后&#xff0c;我们对日志脱敏应该有了一定的理解。 但是实际项目中&#xff0c;我们遇到的情况往往更加复杂&#xff1a; 1&am…

开发云原生应用应遵循的十二要素

代码库&#xff1a;一份版本控制下的基准代码库&#xff0c;多份部署 应用程序的源代码仓库应该只包含一个应用程序&#xff0c;并列出它所依赖的资源清单。对于不同的环境&#xff0c;我们应该不需要重新编译或打包应用程序。每个环境中特有的设置应该与代码无关 依赖&#…

SpringMVC-【回顾】

回顾MVC架构 什么是mvc&#xff1a;模型、视图、控制器 -----软件设计规范 回顾servlet maven项目导入依赖&#xff08;webmvc,servlet-api,jsp-api,jstl,junit&#xff09;创建子模块&#xff0c;在子模块中添加框架支持&#xff08;在子模块中导入依赖jsp、servlet【因为父…

【NACK】视频rtp包接收及nack触发流程走读

这里大神分析很很透彻了:原文地址:WebRTC中NACK的处理流程 - 资料 - 音视频开发中文网 - 构建全国最权威的音视频技术交流分享论坛视频包的接收 RtpVideoStreamReceiver::ReceivePacket void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet)知乎…

聊聊哪些奇葩的代码规范 —— 代码放一行

因为有些要求感觉实是太过奇葩&#xff0c;收集下来娱乐下大家。 代码规范要求 要求代码必须要放在一行上面&#xff0c;导致代码上面有不少行甚至超过了 1000 个字符。 规范解读 就是有时候代码过长&#xff0c;我们会折行增加可读性&#xff0c;最简单的一个例子就是 obj…

CG平台实验——逻辑回归

文章目录 练习2&#xff1a;逻辑回归介绍1 Logistic回归1.1 数据可视化1.2 实现1.2.1 Sigmoid函数1.2.2 代价函数和梯度1.2.2.1 代价函数1.2.2.2 梯度下降 1.2.3 寻找最优参数1.2.4 评估逻辑回归 2 正则化逻辑回归2.1 数据可视化2.2 特征映射2.3 代价函数和梯度 2.4 寻找最优参…

rust疑难进阶手册(1)-安装和管理,类型推断,打印输出(1)

目录 安装管理和配置工具项目管理类型推断格式输出位置参数格式化文本命名参数安装 不管OS是否带有rust,都应使用rustup来安装rust linux/freebsdcurl https://sh.rustup.rs -sSf | shwindows https://www.rust-lang.org/tools/install windows下建议使用GNU的编译链接库,不…

GraphQL入门实战

解决什么问题 根据请求控制返回结果 例如&#xff1a; 一个User对象&#xff0c;有id&#xff0c;name&#xff0c;mobile&#xff0c;email 有些接口只要返回id,name &#xff0c;有些接口还要要返回 mobile 适用场景 弱文档管理&#xff0c;公司对文档要求不高需求复杂变…

【JavaEE进阶】springBoot热部署、请求转发与重定向

目录 一、SpringBoot热部署 1.1热部署的步骤 1.1.1导入maven中央仓库的jar包 1.1.2开启项目自动编译 1.1.3启动项目 1.2热部署的原理 二、请求转发&重定向 2.1关键字不一样 2.2定义不同 请求转发(forward)&#xff1a; 请求重定向(redirect): 2.3数据共享不一样…

如何用MASM32开发Windows应用程序

提醒&#xff1a;以下内容仅做参考&#xff0c;可自行发散。在发布作品前&#xff0c;请把不需要的内容删掉。IT技术日异月异&#xff0c;无论是初学者还是有经验的专业人士&#xff0c;都需要与时俱进&#xff0c;不断学习新技术。在学习一门新的IT技术时&#xff0c;都需要采…

Github自定义个人首页

前言 GitHub 个人主页&#xff0c;官方称呼是 profile&#xff0c;是一个以 Markdown 脚本语言编写的个人 GitHub 展示主页面。Guthub 个人主页可以展示很多有用的信息&#xff0c;例如添加一个首页被访问次数的计数器&#xff0c;一个 Github 被 Star 与 Commit 的概览信息&a…

JVM-学习笔记

一 . JVM架构图 JVM是Java Virtual Machine的简称&#xff0c;意为Java虚拟机。JVM有很多种&#xff0c;使用最为广泛的JVM为HotSpot。 如上面架构图所示&#xff0c;JVM分为三个主要子系统&#xff1a; 类加载器子系统&#xff08;Class Loader Subsystem&#xff09; 运行…

Linux命令学习之cp和mv

cp man 1 cp可以看一下cp的帮助说明。 cp -r /learnwell/good/ /tmp把good目录复制到/tmp目录下&#xff0c;注意想要复制目录&#xff0c;一定要加上-r选项。 接下来学习复制文件&#xff0c;cp 源文件 目标目录&#xff08;相对路径方法&#xff09;或者是cp /源文件所在目…

华为OD机试题【IPv4地址转换成整数】【2023 B卷 100分】

文章目录 &#x1f3af; 前言&#x1f3af; 题目描述&#x1f3af; 解题思路示例 1示例 2&#x1f4d9; Python代码实现&#x1f4d7; Java代码实现&#x1f4d8; C语言代码实现 &#x1f3af; 前言 &#x1f3c6; 《华为机试真题》专栏含2023年牛客网面经、华为面经试题、华为…

Spark安装和编程实践(Spark2.4.0)

系列文章目录 Ubuntu常见基本问题 Hadoop3.1.3安装&#xff08;单机、伪分布&#xff09; Hadoop集群搭建 HBase2.2.2安装&#xff08;单机、伪分布&#xff09; Zookeeper集群搭建 HBase集群搭建 Spark安装和编程实践&#xff08;Spark2.4.0&#xff09; Spark集群搭建 文章目…

linux(信号产生的各种方式)

目录&#xff1a; 1.引入 2.介绍系统支持的信号列表 3.键盘方式产生信号 4.程序中存在异常问题&#xff0c;产生信号 5.系统调用产生信号 6.软件条件也能产生信号 7.任何理解OS给进程发送信号 1.引入 我怎么证明ctrlc是向指定进程发送了2号信号呢&#xff1f;&#xff1f; sig…

5万字大数据实验室建设方案能源大数据中心建设方案word

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除篇幅有限&#xff0c;无法完全展示&#xff0c;喜欢资料可转发评论&#xff0c;私信了解更多信息。 大数据实验室建设方案 大数据实验室建设方案 目录 1概述 1.1建设背景 1.…

chatgpt赋能python:Python抓取数据:从入门到精通

Python抓取数据&#xff1a;从入门到精通 Python是当下最热门的编程语言之一&#xff0c;其强大的数据处理能力使得Python在数据抓取方面也越来越受欢迎。本文将从入门到精通介绍Python抓取数据的方法&#xff0c;希望对初学者有所帮助。 网络爬虫 网络爬虫是Python基于网络…