努力前端【LeetCode-10】448. 找到所有数组中消失的数字 442. 数组中重复的数据(中等) 41. 缺失的第一个正数(困难) [鸽笼原理,数组,Map,类似No.645]
文章目录
- 题目描述-448
- 一、哈希Map
- 二、空间复杂度的优化--鸽笼原理
- 三、总结
- 题目描述-442
- 一、还是hashMap
- 二、继续鸽笼原理
- 题目描述-41
- 一、基础方案
- 二、数组模拟Map
题目描述-448
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1] 输出:[5,6]
示例 2:
输入:nums = [1,1] 输出:[2]
进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、哈希Map
如果只考虑时间复杂度的的话,O(n)还是比较容易地。但是使用Map时,空间复杂度也是O(n)
首先遍历数组建map,然后因为数据是1-n的,所以利用数组长度做遍历条件,map里没有的就是缺失的值。
/*** @param {number[]} nums* @return {number[]}*/
var findDisappearedNumbers = function(nums) {let n = nums.lengthlet map = new Map()nums.forEach(num=>{map.set(num,(map.get(num) || 0) + 1)})let res = []for(let i=1;i<=n;i++){if(!map.get(i)){res.push(i)}}return res
};
二、空间复杂度的优化–鸽笼原理
注意到nums 的长度恰好也为 n,能否让 nums 充当哈希表呢?
由于nums 的数字范围均在 [1,n] 中,我们可以利用这一范围之外的数字,来表达「是否存在」的含义。
这题用鸽笼原理实现,由题意可得,1-n的位置表示1~n个笼子,如果出现过,相应的“鸽笼”就会被占掉,我们将数字置为负数表示被占掉了。 最后再遍历一遍,如果“鸽笼”为正数就是没出现的数字。
这里的站位通常有两种做法:
- 第一种就是置位负数,因为在扫描的时候我们需要把数字还原出来的(这也是仿hash的思想嘛),所以我们套上第一个绝对值保证下标正确,第二个绝对值保证是负数(就表示占上了,不然偶数个不是负负得正了)
- 第二种思路是一样的,可以在对应位置加上数组的长度n,这样每个数肯定就超过数组长度了,没超过的就是缺失的数的index,同样扫描的时候需要先 模N 把数还原回来。
- 两种方法都可,但是n较小时,用n比较好,n大了取反比较好
var findDisappearedNumbers = function(nums) {let res = []nums.forEach(num=>{nums[Math.abs(num) - 1] = - Math.abs(nums[Math.abs(num) - 1])})nums.forEach((num,index)=>{if(num>0) res.push(index + 1)})return res
};
三、总结
注意到nums 的长度恰好也为 n,能否让 nums 充当哈希表呢?
由于nums 的数字范围均在 [1,n] 中,我们可以利用这一范围之外的数字,来表达「是否存在」的含义
在用到map时,需要把空间复杂度从O(n)–>O(1), 可以尝试鸽笼原理
题目描述-442
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。
示例 1: 输入:nums = [4,3,2,7,8,2,3,1] 输出:[2,3]
示例 2: 输入:nums = [1,1,2] 输出:[1]
示例 3: 输入:nums = [1] 输出:[]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-all-duplicates-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、还是hashMap
很简单,直接建立map,次数为2的输出就是了
时间复杂度O(n),空间复杂度O(n)
/*** @param {number[]} nums* @return {number[]}*/
var findDuplicates = function(nums) {let map = new Map()nums.forEach(num=>{map.set(num, (map.get(num) || 0) + 1)})let res = []map.forEach((val,key)=>{if(val==2) res.push(key) })return res
};
二、继续鸽笼原理
跟第一题很类似的思想,因为每个数只出现1次或2次,所以直接在一个每个数的位置上去找,如果大于0证明还没出现过,取反即可,如果已经小于0,证明已经出现过一次,本次是第2次了,符合条件了,直接加到答案数组里就可以了
var findDuplicates = function(nums) {let res = []nums.forEach(num=>{let pos = nums[Math.abs(num) -1]if(pos>0){nums[Math.abs(num) -1] = -pos}else if(pos<0){res.push(Math.abs(num))}})return res
};
题目描述-41
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
示例 1:输入:nums = [1,2,0] 输出:3
示例 2:输入:nums = [3,4,-1,1] 输出:2
示例 3: 输入:nums = [7,8,9,11,12] 输出:1
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/first-missing-positive
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、基础方案
如果本题不要求特定的时间和空间复杂度,那么容易实现。如果数组的长度为 N,
- 我们可以将数组所有的数放入哈希表,随后从 1 开始依次枚举正整数,并判断其是否在哈希表中;
时间复杂度为 O(N),空间复杂度为 O(N) - 我们可以从 1 开始依次枚举正整数,并遍历数组,判断其是否在数组中。
时间复杂度为 O(N^2),空间复杂度为 O(1)
它们都不满足时间复杂度为 O(N)且空间复杂度为 O(1)。
如果我们沿用上面两题的思想,利用数组来模拟hash并存储一些状态,可以修改给定的数组,那么是存在满足要求的算法的。
二、数组模拟Map
算法如下:
- 将数组中所有小于等于 0 的数修改为 N+1,这样保证全为正数,且不会干扰排位
- 我们遍历数组中的每一个数 x,它可能已经被打了标记,因此原本对应的数为 |x|,如果∣x∣∈[1,N],那么我们给数组中的第 |x| - 1个位置的数添加负号。如果它已经有负号,不需要重复添加;
- 在遍历完成之后,如果数组中的每一个数都是负数,那么答案是 N+1,否则答案是第一个正数的位置加 1。
/*** @param {number[]} nums* @return {number}*/
var firstMissingPositive = function(nums) {let n = nums.length//处理负数nums = nums.map(item=>{if(item<=0){return n+1}else{return item}})// 开始放入位置nums.forEach(num=>{let temp = Math.abs(num)if(temp<=n){nums[temp - 1] = - Math.abs(nums[temp - 1])}})//搜寻答案for(let i=0;i<n;i++){if(nums[i]>0){ return i +1 }}// 没有大于0的则表示全命中了return n +1
};
努力前端【LeetCode-10】448. 找到所有数组中消失的数字 442. 数组中重复的数据(中等) 41. 缺失的第一个正数(困难) [鸽笼原理,数组,Map,类似No.645]相关推荐
- Leetcode 40组合总数(回溯)Ⅱ41缺失的第一个正数42接雨水
维护公众号:bigsai ,回复进群加入打卡,回复bigsai分享一些学习资源! 上周第一次 LeetCode 36有效的数独&37解数独(八皇后问题) 上周第二次 LeetCode 38外观 ...
- Leetcode算法Java全解答--41. 缺失的第一个正数
Leetcode算法Java全解答–41. 缺失的第一个正数 文章目录 Leetcode算法Java全解答--41. 缺失的第一个正数 题目 想法 结果 总结 代码 我的答案 大佬们的答案 测试用例 ...
- Java实现 LeetCode 41 缺失的第一个正数
41. 缺失的第一个正数 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: ...
- leetcode —— 41. 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 解题思路: 判断数组中是否存在1,如果没有1则直接返回1,结束: 如果数组长度为1,同时 ...
- LeetCode 41. 缺失的第一个正数
文章目录 1. 题目信息 2. 思路 3. 代码 1. 题目信息 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1:输入: [1,2,0] 输出: 3 示例 2:输入: [3,4, ...
- [Leedcode][JAVA][第41题][缺失的第一个正数][哈希表][数组]
[问题描述][困难] 给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数.示例 1:输入: [1,2,0] 输出: 3 示例 2:输入: [3,4,-1,1] 输出: 2 示例 3:输入: ...
- 【LeetCode笔记】41. 缺失的第一个正数(Java、哈希)
文章目录 题目描述 思路 & 代码 题目描述 难点在于时空复杂度的要求 想出最优方法,需要认真理解题目. 思路 & 代码 做法:建立一个逻辑上的哈希表,令 nums[i] = i + ...
- LeetCode 41. 缺失的第一个正数 First Missing Positive
给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: 输入: [7,8,9,11 ...
- 《LeetCode力扣练习》第448题 找到所有数组中消失的数字 Java
<LeetCode力扣练习>第448题 找到所有数组中消失的数字 Java 一.资源 题目: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内.请你 ...
最新文章
- 一份为高中生准备的机器学习与人工智能入门指南
- (数据结构与算法)递归及一些经典递归问题
- Python编程思想是什么?
- 【Python3网络爬虫开发实战】1.3.4-tesserocr的安装
- jqueryAjax的使用
- Spring生态系统(Spring可能大家都在用,很少去关注整体架构)
- 细数那些年ZStack拿过奖的案例
- php time of 0,PHP程序时出现 Fatal error: Maximum execution time of 30 seconds exceeded in 提示...
- 【新知实验室】-多人视频会议体验
- Mac 苹果电脑创建一个新的管理员账号
- B - Restore Modulo
- golang string转int8_Go教程:23 string转换int类型方法对比
- 漏洞解决方案-Http host头攻击
- 摆脱社恐六部曲, 你可以的!
- 001、element-ui前言
- Docker国内镜像地址和下载安装
- CBOW模型详解(基于one-hot)
- FANUC机器人通过PNS功能实现自动运行
- 美洲杯:阿根廷1-0巴西,梅西破魔咒,阿根廷夺冠
- 【Axure视频教程】中继器表格——设置表格内容