Leetcode 刷题记录 05 —— 普通数组

本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答。

目录

01 最大子数组和

方法一:动态规划(卡达尼算法)

方法二:二分 + 递推

02 合并区间

方法:排序

03 轮转数组

方法:新建数组

04 除自身以外数组的乘积

方法一:左右乘积列表

方法二:左右乘积列表Plus

05 缺失的第一个正数

方法一:哈希映射

方法二:枚举

方法三:数组改造哈希表

方法四:置换


01 最大子数组和

class Solution {
public:int maxSubArray(vector<int>& nums) {}
};
方法一:动态规划(卡达尼算法)
  • 声明 pre,存储 x之前的最大子数组和,pre = max(pre+x, x)

class Solution {
public:int maxSubArray(vector<int>& nums) {int pre = 0, ans = nums[0];for(const auto& x: nums){pre = max(pre+x, x);ans = max(ans, pre);}return ans;}
};
方法二:二分 + 递推
  • 建立结构体 Status,包含 iSum, lSum, rSum, mSum

  • 采用二分,不断切割区间 [l, r],进行递归,快速下降后缓慢回升

  • 注:if(l == r) return (Status) {a[l], a[l], a[l], a[l]};

class Solution {
public:struct Status{int iSum, lSum, rSum, mSum;};//缓慢回升:递推Status pushUp(Status l, Status r){int iSum = l.iSum + r.iSum;int lSum = max(l.lSum, l.iSum + r.lSum);int rSum = max(r.rSum, r.iSum + l.rSum);int mSum = max(max(l.mSum, r.mSum), l.rSum + r.lSum);return (Status) {iSum, lSum, rSum, mSum};}//快速下降:二分Status get(vector<int>& a, int l, int r){if(l == r) return (Status) {a[l], a[l], a[l], a[l]};int m = (l + r) >> 1;Status lSub = get(a, l, m);Status rSub = get(a, m + 1, r);return pushUp(lSub, rSub);}int maxSubArray(vector<int>& nums) {return get(nums, 0, nums.size() - 1).mSum;}
};

02 合并区间

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {}
};
方法:排序
  • sort 原数组

  • 判断 merged.back()[1] < L,若成立,则添加区间,若不成立,则更新原区间右端点

  • 注:if(intervals.size() == 0) return {}; 

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {if(intervals.size() == 0) return {};sort(intervals.begin(), intervals.end());vector<vector<int>> merged;for(int i=0; i<intervals.size(); ++i){int L = intervals[i][0];int R = intervals[i][1];if(!merged.size() || merged.back()[1] < L) merged.push_back({L, R});else merged.back()[1] = max(merged.back()[1], R);}return merged;}
};

03 轮转数组

class Solution {
public:void rotate(vector<int>& nums, int k) {}
};
方法:新建数组
  • 建立新数组 newArr(n),存储轮转结果 newArr[(i+k)%n] = nums[i];

class Solution {
public:void rotate(vector<int>& nums, int k) {int n = nums.size();vector<int> newArr(n);for(int i=0; i<n; ++i){newArr[(i+k)%n] = nums[i];}nums.assign(newArr.begin(), newArr.end());}
};

nums.assign(newArr.begin(), newArr.end()) 意味着用 newArr 中由 begin()end() 界定的元素范围替换 nums 中原有的元素。

04 除自身以外数组的乘积

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {}
};
方法一:左右乘积列表
  • 建立两个数组 leftSup(n)rightSup(n),存储 i 左侧和右侧元素乘积

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int> leftSup(n);leftSup[0] = 1;for(int i=1; i<n; ++i){leftSup[i] = leftSup[i-1] * nums[i-1];}vector<int> rightSup(n);rightSup[n-1] = 1;for(int i=n-2; i>=0; --i){rightSup[i] = rightSup[i+1] * nums[i+1];}vector<int> ans(n);for(int i=0; i<n; ++i){ans[i] = leftSup[i] * rightSup[i];}return ans;}
};
方法二:左右乘积列表Plus
  • 建立一个数组 ans(n),初始存储 i 左侧元素乘积

  • 从右至左,计算 ans(n) 最终值

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int> ans(n);ans[0] = 1;for(int i=1; i<n; ++i){ans[i] = ans[i-1] * nums[i-1];}int R = 1;for(int i=n-1; i>=0; --i){ans[i] = ans[i] * R;R *= nums[i];}return ans;}
};

05 缺失的第一个正数

class Solution {
public:int firstMissingPositive(vector<int>& nums) {}
};
方法一:哈希映射

时间复杂度 O(n)、空间复杂度 O(n)

方法二:枚举

时间复杂度 O(n^2)、空间复杂度 O(1)

方法三:数组改造哈希表

时间复杂度 O(n)、空间复杂度 O(1)

  • 遍历数组,所有复数改为 n + 1

  • 遍历数组,判断 abs(nums[i]) <= n,执行 nums[flag - 1] = -abs(nums[flag - 1]);

  • 遍历数组,若每个数都是负数,则答案为 n + 1,否则为第一个整数位置加一

class Solution {
public:int firstMissingPositive(vector<int>& nums) {int n = nums.size();//改负数for(int i=0; i<n; ++i){if(nums[i] <= 0) nums[i] = n + 1;}//添负号for(int i=0; i<n; ++i){int flag = abs(nums[i]);if(flag <= n) nums[flag - 1] = -abs(nums[flag - 1]);}for(int i=0; i<n; ++i){if(nums[i] > 0) return i + 1; //精髓在负号}return n + 1;}
};
方法四:置换
  • 遍历数组,判断 nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i],交换两数,执行 swap(nums[nums[i] - 1], nums[i])

  • 遍历数组,若 nums[i] != i + 1,则答案为 i + 1, 否则为 n + 1

class Solution {
public:int firstMissingPositive(vector<int>& nums) {int n = nums.size();for(int i=0; i<n; ++i){while(nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]){swap(nums[nums[i] - 1], nums[i]);}}for(int i=0; i<n; ++i){if(nums[i] != i + 1){return i + 1;}}return n + 1;}
};

① 为什么 nums[nums[i] - 1] != nums[i] 改成 nums[i] - 1 != i会导致执行超过时间限制?

nums[nums[i] - 1] != nums[i] 可能是位置不同但数值相同,导致无限循环交换。

② 为什么 nums[i] != i + 1 改成 nums[i] - 1 != i会导致执行错误?

nums[i] - 1 作为索引进行比较时,可能会涉及到为负数或超出范围的索引,若 nums[i] 是负数或 0nums[i] - 1 是非法索引,可能导致未定义行为。

文章部分代码来源于力扣(LeetCode)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QTS单元测试框架

1.QTS单元测试框架介绍 目前QTS项目采用C/C语言,而CppUnit就是xUnit家族中的一员,它是一个专门面向C的单元测试框架。因此,QTS采用CppUnit测试框架是比较理想的选择。 CppUnit按照层次来管理测试,最底层的就是TestCase,当有了几个TestCase以后&#xff0c;可以将它们组织成Te…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12📚页面效…

探索Java多线程的核心概念与实践技巧,带你从入门到精通!

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习多线程编程-"掌握线程创建、管理与安全"&#xff1a; 上一节课程我们铺垫了一系列的东西&#xff0c;引出来了我们的多…

前端数据模拟 Mock.js 学习笔记(附带详细)

前端数据模拟 Mock.js 学习笔记 在前端开发过程中&#xff0c;数据模拟是一项至关重要的环节。当后端接口尚未完成或者需要独立进行前端开发与测试时&#xff0c;Mock.js 能发挥巨大作用&#xff0c;它可以模拟各种数据场景&#xff0c;助力前端开发高效进行。 一、Mock.js 的…

NoteGen是一款开源跨平台的 AI 笔记应用,专注于 recording 和 writing ,基于 Tauri 开发

一、软件介绍 文末提供程序和源码下载 NoteGen 是一款专注于记录和写作的跨平台 AI 笔记应用&#xff0c;基于 Tauri 开发。NoteGen 的核心理念是将记录、写作和 AI 结合使用&#xff0c;三者相辅相成。记录功能可以帮助用户快速捕捉和整理碎片化知识。整理功能是连接记录和写…

学习网络安全需要哪些基础?

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 学习网络安全&#xff0c;对于想要进入IT行业的朋友们来说是一件非常重要的事情。尤其是在当今社会&#xff0c;互联网已经渗透到工作和生活的方方面面&#xff0…

系统安全阶段练习真题(高软44)

系列文章目录 系统安全阶段练习真题 文章目录 系列文章目录前言一、真题总结 前言 本节就是系统安全的阶段练习真题&#xff0c;带答案与解析。 一、真题 总结 就是高软笔记&#xff0c;大佬请略过&#xff01;

C++性能分析工具

C性能分析工具常用的三种。perf、gprof、pprof perf工具需要root权限&#xff0c;设置perf的suid位并不行&#xff0c;需要设置perf对应的内核参数。 perf使用&#xff1a; g -o example example.cpp -O2 # 运行程序并采样 sudo perf record -g ./example # 查看采样结果 sud…

基于PyTorch的深度学习5——神经网络工具箱

可以学习如下内容&#xff1a; • 介绍神经网络核心组件。 • 如何构建一个神经网络。 • 详细介绍如何构建一个神经网络。 • 如何使用nn模块中Module及functional。 • 如何选择优化器。 • 动态修改学习率参数。 5.1 核心组件 神经网络核心组件不多&#xff0c;把这些…

Spring Cloud之注册中心之Nacos负载均衡

目录 负载均衡 服务下线 权重配置 配置权重 解决办法 常见问题 同集群优先访问 给实例配置集群名称 开启Nacos负载均衡策略 负载均衡 ⽣产环境相对是⽐较恶劣的, 我们需要对服务的流量进⾏更加精细的控制. Nacos⽀持多种负载均衡策略, 包括权重, 同机房, 同地域, 同环…

音视频入门基础:RTP专题(16)——RTP封装音频时,音频的有效载荷结构

一、引言 《RFC 3640》和《RFC 6416》分别定义了两种对MPEG-4流的RTP封包方式&#xff0c;这两个文档都可以从RFC官网下载&#xff1a; RFC Editor 本文主要对《RFC 3640》中的音频打包方式进行简介。《RFC 3640》总共有43页&#xff0c;本文下面所说的“页数”是指在pdf阅读…

操作系统控制台-健康守护我们的系统

引言基本准备体验功能健康守护系统诊断 收获提升结语 引言 阿里云操作系统控制平台作为新一代云端服务器中枢平台&#xff0c;通过创新交互模式重构主机管理体验。操作系统控制台提供了一系列管理功能&#xff0c;包括运维监控、智能助手、扩展插件管理以及订阅服务等。用户可以…

ASP.NET Core 6 MVC 文件上传

概述 应用程序中的文件上传是一项功能&#xff0c;用户可以使用该功能将用户本地系统或网络上的文件上传到 Web 应用程序。Web 应用程序将处理该文件&#xff0c;然后根据需要对文件进行一些验证&#xff0c;最后根据要求将该文件存储在系统中配置的用于保存文件的存储中&#…

JVM之Arthas的dashboard命令以及CPU飙高场景

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

JSAR 基础 1.2.1 基础概念_空间小程序

JSAR 基础 1.2.1 基础概念_空间小程序 空间空间自由度可嵌入空间空间小程序 最新的技术进展表明&#xff0c;官网之前的文档准备废除了&#xff0c;基于xsml的开发将退出历史舞台&#xff0c;three.js和普通web结合的技术将成为主导。所以后续学习请移步three.js学习路径&#…

蓝桥杯嵌入式组第七届省赛题目解析+STM32G431RBT6实现源码

文章目录 1.题目解析1.1 分而治之&#xff0c;藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 ADC模块1.3.3 IIC模块1.3.4 UART模块1.3.5 LCD模块1.3.6 LED模块1.3.7 TIM模块 2.源码3.第七届题目 前言&#xff1a;STM32G431RBT6实现嵌入式组第七届题目解析源码&…

Java之IO流

什么是IO流 存储和读取数据的解决方案 I&#xff1a;input:输入 O&#xff1a;output&#xff1a;输出 流&#xff1a;像水流一样传输数据 IO流的作用 用于读取数据&#xff08;本地文件&#xff0c;网络&#xff09; IO流的分类 流的方向&#xff1a; 输入流&#xff…

Python入门———条件、循环

目录 语句 顺序语句 条件语句 缩进和代码块 判断年份是否是闰年 空语句 pass 循环 while 循环 求5的阶乘&#xff1a; 求1&#xff01;2&#xff01;3&#xff01;4&#xff01;5&#xff01; for循环 打印1-10 打印2&#xff0c;4&#xff0c;6&#xff0c;8&#x…

JWT的学习

1、HTTP无状态及解决方案 HTTP一种是无状态的协议&#xff0c;每次请求都是一次独立的请求&#xff0c;一次交互之后就是陌生人。 以CSDN为例&#xff0c;先登录一次&#xff0c;然后浏览器退出&#xff0c;这个时候在进入CSDN&#xff0c;按理说服务器是不知道你已经登陆了&…

【接口负载】✈️整合 Resilience4j 指定接口负载,避免过载

目录 &#x1f44b;前言 &#x1f378;一、应用场景 &#x1f37b;二、 代码实现 &#x1f379;三、扩展 &#x1f378;四、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;上次本地实操了下针对百万级数据量如何快速排序、指定条件获取等&#xff0c;文章内容包括&am…