• leetcode448找到所有数组中消失的数字


    题目:

    给你一个含 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) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。


    解决:

    解法1:直接用哈希表

    引入hashmap,记录在数组nums中出现的数值,再通过检索hashmap就可以找到哪些是在hashmap中没有出现的。把没有的放进list。不过使用hashmap就不符合进阶要求中的“不使用额外空间”这一条。

    1. public List findDisappearedNumbers(int[] nums) {
    2. HashMap hash = new HashMap<>();
    3. for (int i = 0; i < nums.length; i++) {
    4. hash.put(nums[i],true);
    5. }
    6. List list = new LinkedList<>();
    7. for (int i = 1; i <= nums.length ; i++) {
    8. if(!hash.containsKey(i)){
    9. list.add(i);
    10. }
    11. }
    12. return list;
    13. }

    由于数字范围均在[1,n]中,可以用一个长度为你的数组来代替哈希表。利用区间之外的数字来记录数组元素,比如都加某个值,或者把数组元素都变成负的。就是下面的解法2和3。


    解法2:变负数法

    例:数组[4,3,2,7,8,2,3,1]

    将这些整数作为数组下标,将对应的数组置为负值,找遍历完后是正数的。

    从第0个元素开始,4-1=3,则把下标为3的数的值,即7变为负,即改为-7

    第1个元素,3-1=2,则把下标为2的数的值,即2变为负,即改为-2

    第2个元素,-2-1=-3,则把下标为-3的数的值,即下标为5的数变为负,即-2

    第3个元素,-7-1=-8,则把下标为0的数的值改为负,即-4

    第4个元素,8-1=7,则把下标为7的元素改为负,即-1

    第5个元素,-2-1=-3,则把下标为-3的元素改为负,即2

    第6个元素,3-1=2,则把下标为2的元素改为负,即-2

    第7个元素,-1-1=-2,则把下标为-2的元素改为负,即下标为6的元素改为负,即-3

    遍历完数组后我们发现,数组变成了[-4,-3,-2,-7,8,2,-3,-1],则只有下标为4和5的数没有变成负数,则缺失的就是4+1=5,以及5+1=6。

    又比如数组中没有消失的数字,[3,2,1,4,5]

    第0个元素,3-1=2,则下标为2的元素改为负,即1变成-1

    第1个元素,2-1=1,则下标为1的元素改为负,即2变成-2

    第2个元素,-1-1=-2,则下标为3的元素改为负,即4变成-4

    第3个元素,-4-1=-5,则下标为0的元素改为负,即3变成-3

    第4个元素,5-1=4,则下标为4的元素改为负,即5变成-5

    遍历完数组后我们发现,数组中所有元素都变成负数了,则没有缺失的数字。

    1. public List findDisappearedNumbers(int[] nums) {
    2. List results = new ArrayList<>();
    3. for(int i = 0 ; i< nums.length;i++)
    4. {
    5. if(nums[Math.abs(nums[i])-1]>0)
    6. {
    7. nums[Math.abs(nums[i])-1] = -nums[Math.abs(nums[i])-1];
    8. }
    9. }
    10. for(int i =0;i
    11. {
    12. if(nums[i]>0)
    13. {
    14. results.add(i+1);
    15. }
    16. }
    17. return results;
    18. }

    或者

    1. public List findDisappearedNumbers(int[] nums) {
    2. //用来存放结果
    3. List res = new ArrayList<>();
    4. //1. 遍历下数组的元素,对对应的索引位置的元素作标记
    5. int len = nums.length;
    6. for(int i = 0; i < len; i++){
    7. int num = Math.abs(nums[i]); //由于数组的元素有可能被*-1,所以取绝对值
    8. int index = num - 1;
    9. if(nums[index] > 0){
    10. nums[index] *= -1;
    11. }
    12. }
    13. // 寻找没有标记的索引位置
    14. for(int i = 0; i < len; i++){
    15. if(nums[i] > 0){
    16. int num = i + 1; //将索引转化为对应的元素
    17. res.add(num);
    18. }
    19. }
    20. return res;
    21. }

    解法3:加数字法

    加数字的话要注意,加完后的数不能在原始数组中出现过。由于数组区间是1到n,则加n,加完后最小的也是n+1。将原数组当成哈希表,用每个数对长度n取余,取余后的数一定都小于n,再将这个数加n,遍历数组,当数组中的数小于n时说明数缺失了。

    1. public List findDisappearedNumbers(int[] nums) {
    2. int n=nums.length;
    3. for(int num : nums){
    4. int x=(num-1)%n;//对n取模来还原它本来的值
    5. nums[x]+=n;
    6. }
    7. List result=new ArrayList();
    8. for(int i=0;i
    9. if(nums[i]<=n){
    10. result.add(i+1);
    11. }
    12. }
    13. return result;
    14. }

    加油加油^_^

  • 相关阅读:
    Oracle 中文排序 Oracle 中文字段排序
    windows onlyoffice教程
    动态新增、修改Logback的Appender(可实现动态调整日志级别,Appender参数)
    2022年首家民营征信机构浙江同信获企业征信备案公示
    .Net中跨域问题
    善用浏览器的一些调试技巧
    【PyTorch】PyTorch基础知识——张量
    笔记53:torch.nn.rnn() 函数详解
    【网页设计】HTML做一个属于我的音乐页面(纯html代码)
    2022年湖北武汉安全员ABC考试题库有吗?甘建二
  • 原文地址:https://blog.csdn.net/nameofworld/article/details/132691479