文章目录

  • 题目描述-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]相关推荐

  1. Leetcode 40组合总数(回溯)Ⅱ41缺失的第一个正数42接雨水

    维护公众号:bigsai ,回复进群加入打卡,回复bigsai分享一些学习资源! 上周第一次 LeetCode 36有效的数独&37解数独(八皇后问题) 上周第二次 LeetCode 38外观 ...

  2. Leetcode算法Java全解答--41. 缺失的第一个正数

    Leetcode算法Java全解答–41. 缺失的第一个正数 文章目录 Leetcode算法Java全解答--41. 缺失的第一个正数 题目 想法 结果 总结 代码 我的答案 大佬们的答案 测试用例 ...

  3. Java实现 LeetCode 41 缺失的第一个正数

    41. 缺失的第一个正数 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: ...

  4. leetcode —— 41. 缺失的第一个正数

    给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 解题思路: 判断数组中是否存在1,如果没有1则直接返回1,结束: 如果数组长度为1,同时 ...

  5. LeetCode 41. 缺失的第一个正数

    文章目录 1. 题目信息 2. 思路 3. 代码 1. 题目信息 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1:输入: [1,2,0] 输出: 3 示例 2:输入: [3,4, ...

  6. [Leedcode][JAVA][第41题][缺失的第一个正数][哈希表][数组]

    [问题描述][困难] 给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数.示例 1:输入: [1,2,0] 输出: 3 示例 2:输入: [3,4,-1,1] 输出: 2 示例 3:输入: ...

  7. 【LeetCode笔记】41. 缺失的第一个正数(Java、哈希)

    文章目录 题目描述 思路 & 代码 题目描述 难点在于时空复杂度的要求 想出最优方法,需要认真理解题目. 思路 & 代码 做法:建立一个逻辑上的哈希表,令 nums[i] = i + ...

  8. LeetCode 41. 缺失的第一个正数 First Missing Positive

    给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: 输入: [7,8,9,11 ...

  9. 《LeetCode力扣练习》第448题 找到所有数组中消失的数字 Java

    <LeetCode力扣练习>第448题 找到所有数组中消失的数字 Java 一.资源 题目: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内.请你 ...

最新文章

  1. 一份为高中生准备的机器学习与人工智能入门指南
  2. (数据结构与算法)递归及一些经典递归问题
  3. Python编程思想是什么?
  4. 【Python3网络爬虫开发实战】1.3.4-tesserocr的安装
  5. jqueryAjax的使用
  6. Spring生态系统(Spring可能大家都在用,很少去关注整体架构)
  7. 细数那些年ZStack拿过奖的案例
  8. php time of 0,PHP程序时出现 Fatal error: Maximum execution time of 30 seconds exceeded in 提示...
  9. 【新知实验室】-多人视频会议体验
  10. Mac 苹果电脑创建一个新的管理员账号
  11. B - Restore Modulo
  12. golang string转int8_Go教程:23 string转换int类型方法对比
  13. 漏洞解决方案-Http host头攻击
  14. 摆脱社恐六部曲, 你可以的!
  15. 001、element-ui前言
  16. Docker国内镜像地址和下载安装
  17. CBOW模型详解(基于one-hot)
  18. FANUC机器人通过PNS功能实现自动运行
  19. 美洲杯:阿根廷1-0巴西,梅西破魔咒,阿根廷夺冠
  20. 【Axure视频教程】中继器表格——设置表格内容

热门文章

  1. 三本可爱小表妹,面试小米Java技术岗经验分享(已拿offer)
  2. 8家公司笔面试经历-百度-联发科-瑞晟
  3. 学习人工智能可以从事哪些职业,有哪些就业前景和薪资待遇?
  4. 快速过一遍计算机基础--操作系统—4.文件管理
  5. docx4j生成Word添加页眉页脚水印 页眉页脚奇偶显示首页显示
  6. arange和range
  7. 用FPGA实现深度卷积神经网络(5)
  8. Linux双网卡双ip配置
  9. Tomcat 环境变量配置
  10. 南宁供电局抄表及电量电费管理系统的开发设计