题目

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

Example 1:

  1. Input: [3,0,1]
  2. Output: 2

Example 2:

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

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?


题意

给定一个长度为n的数组,从 0-n 这 n+1 个数中选取 n 个数填充入数组中,找到缺失的那一个数。

思路

交换法:第一次遍历数组,将nums[i]与下标为nums[i]的数进行交换,第二次遍历数组,如果遇到 i != nums[i],说明i就是缺失的数。

求和法:先求 0-n 的和,再求数组中数的和,相减就是缺失的数。

异或法:根据相同的数异或为0的性质, 将数组中所有数异或一遍,再将结果与 0-n 异或一遍,相同的数会互相抵消,得到的结果就是缺失的数。


代码实现

Java

交换

  1. class Solution {
  2. public int missingNumber(int[] nums) {
  3. int i = 0;
  4. while (i < nums.length) {
  5. if (nums[i] >= nums.length || nums[i] == i) {
  6. i++;
  7. } else {
  8. swap(nums, i, nums[i]);
  9. }
  10. }
  11. for (int j = 0; j < nums.length; j++) {
  12. if (nums[j] != j) {
  13. return j;
  14. }
  15. }
  16. return nums.length;
  17. }
  18. private void swap(int[] nums, int i, int j) {
  19. int tmp = nums[i];
  20. nums[i] = nums[j];
  21. nums[j] = tmp;
  22. }
  23. }

求和

  1. class Solution {
  2. public int missingNumber(int[] nums) {
  3. int len = nums.length;
  4. int sum1 = (len + 1) * len / 2;
  5. int sum2 = 0;
  6. for (int num : nums) {
  7. sum2 += num;
  8. }
  9. return sum1 - sum2;
  10. }
  11. }

异或

  1. class Solution {
  2. public int missingNumber(int[] nums) {
  3. int res = 0;
  4. for (int i = 0; i < nums.length; i++) {
  5. res = res ^ nums[i] ^ (i + 1);
  6. }
  7. return res;
  8. }
  9. }

JavaScript

  1. /**
  2. * @param {number[]} nums
  3. * @return {number}
  4. */
  5. var missingNumber = function (nums) {
  6. let i = 0;
  7. while (i < nums.length) {
  8. let j = nums[i]
  9. if (nums[i] === nums[j] || nums[i] === i) {
  10. i++
  11. } else {
  12. [nums[i], nums[j]] = [nums[j], nums[i]]
  13. }
  14. }
  15. i = 0
  16. while (i < nums.length) {
  17. if (i !== nums[i]) return i
  18. i++
  19. }
  20. return i
  21. };