Topic
- Array
- Math
- Bit Manipulation
Description
https://leetcode.com/problems/missing-number/
Given an array nums
containing n
distinct numbers in the range [0, n]
, return the only number in the range that is missing from the array.
Follow up: Could you implement a solution using only O(1)
extra space complexity and O(n)
runtime complexity?
Example 1:
Input: nums = [3,0,1]
Output: 2
Explanation: n = 3 since there are 3 numbers, so all numbers are in the range [0,3]. 2 is the missing number in the range since it does not appear in nums.
Example 2:
Input: nums = [0,1]
Output: 2
Explanation: n = 2 since there are 2 numbers, so all numbers are in the range [0,2]. 2 is the missing number in the range since it does not appear in nums.
Example 3:
Input: nums = [9,6,4,2,3,5,7,0,1]
Output: 8
Explanation: n = 9 since there are 9 numbers, so all numbers are in the range [0,9]. 8 is the missing number in the range since it does not appear in nums.
Example 4:
Input: nums = [0]
Output: 1
Explanation: n = 1 since there is 1 number, so all numbers are in the range [0,1]. 1 is the missing number in the range since it does not appear in nums.
Constraints:
n == nums.length
1 <= n <= 10⁴
0 <= nums[i] <= n
- All the numbers of
nums
are unique.
Analysis
方法一:我写的。位操作,整型符号用来作标记。
方法二:所有下标与元素累异或。
方法三:利用数学求和公式。
方法四:数学上此消彼长。
方法五:排序 + 二分查找。
Submission
import java.util.Arrays;
public class MissingNumber {
// 方法一:我写的
public int missingNumber1(int[] nums) {
for (int i = 0; i < nums.length; i++) {
int targetIndex = nums[i] & Integer.MAX_VALUE;
if (targetIndex < nums.length) {
nums[targetIndex] |= Integer.MIN_VALUE;
}
}
int result = nums.length;
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= 0)
result = i;
nums[i] &= Integer.MAX_VALUE;// 复原
}
return result;
}
// 方法二:所有下标与元素累异或
public int missingNumber2(int[] nums) { // xor
int res = nums.length;
for (int i = 0; i < nums.length; i++) {
res ^= i ^ nums[i];
}
return res;
}
// 方法三:数学求和公式
public int missingNumber3(int[] nums) { // sum
int len = nums.length;
int sum = len * (len + 1) / 2;
for (int i = 0; i < len; i++)
sum -= nums[i];
return sum;
}
// 方法四:数学上此消彼长
public int missingNumber4(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++)
sum += nums[i] - i;
return nums.length - sum;
}
// 方法五:排序 + 二分查找
public int missingNumber5(int[] nums) { // binary search
Arrays.sort(nums);
int left = 0, right = nums.length, mid = left + (left - right) / 2;
while (left < right) {
mid = (left + right) / 2;
if (nums[mid] > mid)
right = mid;
else
left = mid + 1;
}
return left;
}
}
Test
import static org.junit.Assert.*;
import org.junit.Test;
public class MissingNumberTest {
@Test
public void test() {
MissingNumber obj = new MissingNumber();
assertEquals(2, obj.missingNumber1(new int[] {3, 0, 1}));
assertEquals(2, obj.missingNumber1(new int[] {0, 1}));
assertEquals(8, obj.missingNumber1(new int[] {9, 6, 4, 2, 3, 5, 7, 0, 1}));
assertEquals(1, obj.missingNumber1(new int[] {0}));
assertEquals(2, obj.missingNumber2(new int[] {3, 0, 1}));
assertEquals(2, obj.missingNumber2(new int[] {0, 1}));
assertEquals(8, obj.missingNumber2(new int[] {9, 6, 4, 2, 3, 5, 7, 0, 1}));
assertEquals(1, obj.missingNumber2(new int[] {0}));
assertEquals(2, obj.missingNumber3(new int[] {3, 0, 1}));
assertEquals(2, obj.missingNumber3(new int[] {0, 1}));
assertEquals(8, obj.missingNumber3(new int[] {9, 6, 4, 2, 3, 5, 7, 0, 1}));
assertEquals(1, obj.missingNumber3(new int[] {0}));
assertEquals(2, obj.missingNumber4(new int[] {3, 0, 1}));
assertEquals(2, obj.missingNumber4(new int[] {0, 1}));
assertEquals(8, obj.missingNumber4(new int[] {9, 6, 4, 2, 3, 5, 7, 0, 1}));
assertEquals(1, obj.missingNumber4(new int[] {0}));
assertEquals(2, obj.missingNumber5(new int[] {3, 0, 1}));
assertEquals(2, obj.missingNumber5(new int[] {0, 1}));
assertEquals(8, obj.missingNumber5(new int[] {9, 6, 4, 2, 3, 5, 7, 0, 1}));
assertEquals(1, obj.missingNumber5(new int[] {0}));
}
@Test
public void testOther() {
assertEquals(0 | 1 << 31, Integer.MIN_VALUE) ;
assertEquals((0 | 1 << 31) - 1, Integer.MAX_VALUE) ;
}
}