Leetcode 之 Set Mismatch
645. Set Mismatch
1.Problem
The set S
originally contains numbers from 1 to n
. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.
Given an array nums
representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.
Example 1:
Input: nums = [1,2,2,4] Output: [2,3]
Note:
- The given array size will in the range [2, 10000].
- The given array's numbers won't have any order.
2.Solution
题目的大意是原本集合S,包含1到n中的所有数,但1~n中的某个数出现了错误,可以理解为1~n中的某个数x变成了另一个数y,这样集合S中就出现了2个y,且丢失了x,返回数组[x,y]
3.Code
//先找出 出现重复的那个数,再找出缺失的那个数,时间复杂度为O(N),空间复杂度为O(N)
class Solution { public int[] findErrorNums(int[] nums) { int[] temp = new int[nums.length + 1]; int[] res = new int[2]; for ( int i = 0 ; i < nums.length ; i++ ) { if ( temp[nums[i]] == 0 ) { temp[nums[i]] = 1; } else { temp[nums[i]] = 0; res[0] = nums[i]; } } for ( int i = 1 ; i <= nums.length ; i++ ) { if ( temp[i] == 0 && i != res[0] ) { res[1] = i; } } return res; } }
//时间复杂度O(N),空间复杂度O(1)
class Solution { public int[] findErrorNums(int[] nums) { int duplicates = 0; int miss = 0; for (int i = 0 ; i < nums.length ; i++ ) { if ( nums[ Math.abs(nums[i]) - 1 ] < 0 ) { duplicates = Math.abs(nums[i]); } else { nums[ Math.abs(nums[i]) - 1 ] *= -1; } } for ( int i = 0 ; i < nums.length ; i++ ) { if ( nums[i] > 0 ) { miss = i + 1; } } return new int[]{duplicates,miss}; } }
//时间复杂度O(N),空间复杂度O(1),利用位操作思想,将duplicate和miss找出来,注释已经很详细了,此处不赘述解题思想
class Solution { public int[] findErrorNums(int[] nums) { int xor = 0 , xora = 0 , xorb = 0; for ( int i = 0 ; i < nums.length ; i++ ) { xor ^= nums[i]; } for ( int i = 1 ; i <= nums.length ; i++ ) { xor ^= i; } //xor = duplicates ^ miss; //想办法从xor中分离出duplicate 和 miss //先从xor中分离出左右的为1的那位,利用这个可以将duplicate和miss分开 int separate = xor & ( ~( xor - 1 ) ); for ( int i = 0 ; i < nums.length ; i++ ) { if ( (separate & nums[i]) != 0 ) { xora ^= nums[i]; //此处写xora 还是 xorb都可以,只要跟下面一个循环对应起来就ok } else { xorb ^= nums[i]; } } for ( int i = 1 ; i <= nums.length ; i++ ) { if ( (separate & i) != 0 ) { xora ^= i; //跟上面对应 } else { xorb ^= i; } } //此时的xora、xorb 中一个是duplicates,另一个是miss //如果xora出现在了nums数组中,那其一定是duplicate,反之则是miss for ( int a : nums ) { if ( a == xora ) { return new int[]{xora,xorb}; } } return new int[]{xorb,xora}; } }