Leetcode problem solution-448. Find all the missing numbers in the array

Topic link

Title description:

Given an integer array with a range of 1 ≤ a[i] ≤ n (n = array size), some elements in the array appear twice, and some only appear once.

Find all the numbers in the range [1, n] that do not appear in the array.

Can you accomplish this task without using extra space and the time complexity is O(n)? You can assume that the returned array is not included in the extra space.

Example:

Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]


Idea 1

  The title gave two key conditions, one is that the range of array elements is ** 1 ≤ a[i] ≤ n (n = the size of the array) **; the second is that the number of occurrences of array elements is either twice or once, which is Problem solving creates a premise. This easily reminds us of "a radish per pit". Now the "radish" is messy. How can we return the radish to its own pit? If the "radish" returns to its own corresponding pit, the repeated radishes will be scattered in other pits, and the "radish" that should have been corresponding to these "other pits" is the output result. In other words, it is sorted by index~ It
  is too abstract to say, drawing a schematic diagram is helpful to understand~
Insert picture description here

  In addition, [2,1]a judgment is added for a test case .

if(nums[i] != i + 1)
   nums[i] = temp;


Code

class Solution {
    
    
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
    
    
        for(int i = 0; i < nums.size(); i++){
    
    
            if(nums[i] != i + 1){
    
    
                int temp = nums[i];
                while(nums[temp - 1] != temp){
    
    
                    int record = nums[temp - 1];
                    nums[temp - 1] = temp;
                    temp = record;
                }
                //添加判断
                if(nums[i] != i + 1)
                    nums[i] = temp;
            }
        }

        vector<int> result;
        for(int i = 0; i < nums.size(); i++)
            if(nums[i] != i + 1)
                result.push_back(i + 1);

        return result;
    }
};

Idea 2

  The advanced level requires time complexity of O(n). Obviously Idea 1 cannot meet this requirement, so we need to think further. In fact, if the space complexity O(1) is not required, we can use a hash table to store it, and find the number that does not appear.
  So can we build a simple hash table in the original array? Traverse the array and take the opposite of the value under the index corresponding to the array element. Obviously, the element that does not appear cannot change the value under its corresponding index to a negative number, that is to say, traverse the array again, who is a positive number , Then the positive number is the number 索引 + 1that did not appear.

Original array: [4, 3, 2, 7, 8, 2, 3, 1]
Now array: [-4, -3, -2, -7, 8, 2, -3, -1]


Code

class Solution {
    
    
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
    
    
        for(int i = 0; i < nums.size(); i++){
    
    
            int loc = abs(nums[i]) - 1;
            if(nums[loc] > 0)
                nums[loc] *= -1;
        }

        vector<int> result;
        for(int i = 0; i < nums.size(); i++)
            if(nums[i] > 0)
                result.push_back(i + 1);

        return result;
    }
};


If there are mistakes or not rigorous, please correct me, thank you very much.
My blog: http://breadhunter.gitee.io

Guess you like

Origin blog.csdn.net/weixin_40807714/article/details/105166487