• LeetCode刷题之数组篇(二)


    目录

    645.错误的集合   难度:简单

    题目描述

    解题思路

    代码演示

    448.找到所有数组中消失的数字   难度:简单

    题目描述

    解题思路

    代码演示

    442.数组中重复的数据  难度:中等

    题目描述

    解题思路

    代码演示

    总结


    645.错误的集合   难度:简单

    题目描述

    集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。

    给定一个数组 nums 代表了集合 S 发生错误后的结果。

    请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

    示例 1:

    输入:nums = [1,2,2,4]
    输出:[2,3]


    示例 2:

    输入:nums = [1,1]
    输出:[1,2]

    提示:

    2 <= nums.length <= 104
    1 <= nums[i] <= 104

    解题思路

    找重复元素:排序,相邻两个元素相同则即为重复的元素。
    找丢失的元素:分情况讨论


    注意这种题不能用[i]与[i+1]比较,换种比较方法,记录前一个的元素,再在下一次循环中与下一个的元素比较,相当于[i]与[i+1]比较。


    1.丢失的可能是1,即22,所以上一个元素要初始化为0,不然循环后找不到丢失的元素1。
    2.排序后如果两相邻两元素之差大于1,则前一个元素+1即为丢失的元素。
    3.特殊情况如11,122,相邻两元素之差都不大于1,只需比较最后一个元素与它对于的坐标是否相等,如果不相等,则丢失的是最后一个元素的下标.如11,nums.size()=2,nums[2-1]=1,2!=1,丢失为2。

    代码演示

    1. class Solution {
    2. public:
    3. vector<int> findErrorNums(vector<int>& nums) {
    4. vector<int>v(2);
    5. sort(nums.begin(),nums.end());
    6. int prev=0,n=nums.size();
    7. for(int i=0;i
    8. if(nums[i]==prev){
    9. v[0]=prev;
    10. }
    11. else if(nums[i]-prev>1){
    12. v[1]=prev+1;
    13. }
    14. prev=nums[i];
    15. }
    16. if(nums[n-1]!=n)
    17. v[1]=n;
    18. return v;
    19. }
    20. };

    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]

    提示:

    n == nums.length
    1 <= n <= 105
    1 <= nums[i] <= n
    进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。

    解题思路

    注意时间复杂度为 O(n),不能使用sort比较再遍历。

    看了答案想了许久都没想明白,后面看到一个博主说的才豁然开朗->找到所有数组中消失的数字


    思路:使用+n的方法
    把每个元素-1变为索引,利用for循环将每个索引相应的值加上num.size(),如果后面数值小于等于num.size(),则索引不存在,即索引+1(原数组的值)不存在。

    为什么要取余呢?因为重复的元素加num.size()之后数值大于他了,如果不取余就找不到下标了

    4 3 2 7 8 2 3 1->12 19 18 15 8 2 11 9
    为什么8和2没变呢,因为他们的索引不存在!!!--->即索引+1原数组的值不存在!!!

    代码演示

    1. class Solution {
    2. public:
    3. vector<int> findDisappearedNumbers(vector<int>& nums) {
    4. vector<int>res;
    5. for(int i=0;isize();i++){
    6. int index=(nums[i]-1)%nums.size();
    7. nums[index]+=nums.size();
    8. }
    9. for(int i=0;isize();i++){
    10. if(nums[i]<=nums.size())
    11. res.push_back(i+1);
    12. }
    13. return res;
    14. }
    15. };

    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]
    输出:[]

    提示:

    n == nums.length
    1 <= n <= 105
    1 <= nums[i] <= n
    nums 中的每个元素出现 一次 或 两次

    解题思路

    和上面一题一样的,不过是求重复的
    思路:使用+n的方法
    把每个元素-1变为索引,利用for循环将每个索引相应的值加上num.size(),如果后面数值大于num.size()的两倍(即加了两次),则索引重复,即索引+1(原数组的值)重复。
    4 3 2 7 8 2 3 1->12 19 18 15 8 2 11 9
    19 和18大于2*8,即索引+1原数组的值重复。

    代码演示

    1. class Solution {
    2. public:
    3. vector<int> findDuplicates(vector<int>& nums) {
    4. vector<int>res;
    5. for(int i=0;isize();i++){
    6. int index=(nums[i]-1)%nums.size();
    7. nums[index]+=nums.size();
    8. }
    9. for(int i=0;isize();i++){
    10. if(nums[i]>2*nums.size()){
    11. res.push_back(i+1);
    12. }
    13. }
    14. return res;
    15. }
    16. };

    总结

    自己想不出来,有时看了答案都需要一些时间才能懂,不过相信自己,才刚开始呢!

  • 相关阅读:
    qt 在下安装闪退 退出的解决方案
    查看麒麟操作系统版本
    计算机毕业设计之java+springboot基于vue的乐校园二手书交易管理系统
    opengl灯光基础:2.1 光照基础知识
    使用git版本控制工具,实现本地代码库与远程代码库的互传
    全球地表水数据集JRC Global Surface Water Mapping Layers, v1.2数据
    民安智库(第三方市场调查公司)北京汽车神秘顾客调查
    最全解决:微服务之间调用出现Load balancer does not have available server for client
    猿创征文丨赶紧进来修内功!!! 详细讲解数据在内存中的存储(浮点数篇)
    2021年全国职业院校技能大赛高职组“软件测试”赛项—“阶段二竞赛任务书”
  • 原文地址:https://blog.csdn.net/btufdycxyffd/article/details/126869340