消失的两个数

目录

  • 题目
  • 题解
    • 方法一 借助一个数组标记存在的数
    • 方法二 等差数列求和公式

题目

力扣原题:原题链接
出现形式:原题重现
模式:核心代码模式
题目描述:
消失的两个数_第1张图片

题解

方法一 借助一个数组标记存在的数

思路: 利用数组下标和数据都是从1到N的连续性,把数组从1开始的下标对应1到N的数据;然后对应下表存储的值表示这个值是否存在。然后遍历的时候,把不存在的数保存到结果数组中。

  1. 确定辅助数组的长度
    根据题意,题目中明确只消失了两个,所以可以根据跟定数组的长度来计算辅助数组的长度。但是因为下表从0开始,而整数从1开始,所以为了保存1到N的整数,需要在给定数组长度的基础上加3
  2. 存在标记如何设计
    辅助数组可以用不同的数据类型,如果使用int型,可以随便指定1或0和存在与否的关系,也可以利用boolean类型或者其他类型。我选择的是用1表示存在,0表示不存在。这样的话因为JAVA本身int的默认值就是0,就只需要在某个数存在时修改为1。

代码实现:

class Solution {
    public int[] missingTwo(int[] nums) {
        //数组的所有长度
        /*
        用一个长度为nums + 3的数组标记出现的数,如果nums中出现某个数,则对应下标的内容置为1,表示出现过
        从1开始遍历,内容为0的下标即为缺失的数
         */
        int arr[] = new int[nums.length + 3];
        //空间复杂度不符,这里空间复杂度:O(n)
        int res[] = new int[2];
      
        for(int i = 0; i < nums.length; i++){
           arr[nums[i]] = 1;
        }
        int index = 0;//用来定位结果应该放在第几位
        for(int i = 1; i < arr.length; i++){
            if(arr[i] == 0){
                res[index] = i;
                index++;
            }
        }   
        return res;
    }
}

这个思路,从理论上分析,我觉得空间复杂度应该是不满足的,但是不知道为什么可以通过,因为题目要求的是空间复杂度应该为O(1),但我这样做应该是O(n).

  • 知识点
    虽然从复杂度上看可能不太理想,但是思路中利用数组下标和数据的对应关系,实现键值存储的想法,我觉得是比较巧妙。这个思路应该是之前刷过的题中出现的,所以看到的时候才会突然想到。

方法二 等差数列求和公式

力扣题解
思路:
整体思路就是利用2次利用实际和与理论和的差

  • 第一次确定两个消失值的和
  • 第二次确定消失值的其中一个
    剩下一个就可以通过和减去求得的这个即可。利用这种方式可以达到空间复杂度为O(1)的效果。

代码实现

class Solution {
    public int[] missingTwo(int[] nums) {
        int sum = 0;//保存实际的和
        for(int i : nums){
           sum += i;
        }
        
        int n = nums.length +2;
        int sumOfMis = (1 + n) * n / 2 - sum;//缺失值的和
        
        int halfMiSum = ts / 2;//缺失值和的一半
        sum = 0;//第二次利用实际与理论值的和差
        for(int i : nums){
            if(i <= m){
                sum += i;
            }
        }
        int res = (1 + m) * m /2 - sum;
        //以两值和的一半为界,在左半部分找到较小的那个值。
        return new int[]{res, ts - res};
    }
}
  • 题解关键点
    有公式可以利用

你可能感兴趣的:(力扣刷题,leetcode,算法,数据结构)