<leetcode>268. Missing Number
2016-12-15 10:36
183 查看
Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
For example,
Given nums = [0, 1, 3] return 2.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
看了discuss之后,总结了三种解法:
1、最直接的解法就是用不差数的数组元素之和减去给定数组元素的和,得到的结果就是丢失的数(不差数的数组其实就是一个等差数列)
代码实现:
注意等差数列的求和公式:Sn=na1+n(n-1)d/2
2、使用位运算,异或的特性就是“相异为一,相同为零”,到十进制表现为a^b^b=a,所以我们将缺数的数组与完整的数组进行异或,最后得到的结果就是丢失的数(只有该数没有相同的数进行匹配)
代码实现:
更简洁的代码写法:可以直接定义res = nums.length;
3、使用二分查找,当然,如果给定数组没有排好序,则我们还要先排序才能进行二分查找,显然不符合线性时间复杂度的要求,所以,使用二分茶渣的前提是给定数组已经排好序了,此时使用二分查找效率会明显高于上面两种方法。
思路:对于已经排好序的数组,如果数字没有丢失,那么元素的值跟下标应该是相等的,一旦出现了元素值大于下标,则说明丢失的元素在该位置的左边,反之,则在右边。
代码实现:
For example,
Given nums = [0, 1, 3] return 2.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
看了discuss之后,总结了三种解法:
1、最直接的解法就是用不差数的数组元素之和减去给定数组元素的和,得到的结果就是丢失的数(不差数的数组其实就是一个等差数列)
代码实现:
public class Solution { public int missingNumber(int[] nums) { int n = nums.length; int sum = n * (n + 1)/2; int sum1 = 0; for (int num : nums){ sum1 += num; } return sum - sum1; } }
注意等差数列的求和公式:Sn=na1+n(n-1)d/2
2、使用位运算,异或的特性就是“相异为一,相同为零”,到十进制表现为a^b^b=a,所以我们将缺数的数组与完整的数组进行异或,最后得到的结果就是丢失的数(只有该数没有相同的数进行匹配)
代码实现:
public class Solution { public int missingNumber(int[] nums) { int res = 0; int i = 0; for (; i < nums.length; i++){ res ^= i ^ nums[i]; } return res ^ i; } }
更简洁的代码写法:可以直接定义res = nums.length;
public class Solution { public int missingNumber(int[] nums) { int res = nums.length;//就相当于上面代码块中最后返回值运算的i for (int i = 0; i < nums.length; i++){ res 4000 ^= i ^ nums[i]; } return res; } }
3、使用二分查找,当然,如果给定数组没有排好序,则我们还要先排序才能进行二分查找,显然不符合线性时间复杂度的要求,所以,使用二分茶渣的前提是给定数组已经排好序了,此时使用二分查找效率会明显高于上面两种方法。
思路:对于已经排好序的数组,如果数字没有丢失,那么元素的值跟下标应该是相等的,一旦出现了元素值大于下标,则说明丢失的元素在该位置的左边,反之,则在右边。
代码实现:
public class Solution { public int missingNumber(int[] nums) { Arrays.sort(nums); int left = 0; int right = nums.length; int mid = 0; while (left < right){ mid = (left + right) / 2; if (nums[mid] > mid){ right = mid; } else { left = mid + 1; } } return right; } }
相关文章推荐
- <LeetCode><Easy> 171 Excel Sheet Column Number
- <LeetCode> 题8:旋转字符串
- <Leetcode>Median of Two Sorted Arrays
- <fmt:formatNumber>标签
- <LeetCode> Single Number
- <LeetCode><Easy>290 Word Pattern
- <LeetCode><Easy> 190 Revese Bits
- <LeetCode><Medium> 3 Longest Substring Without Repeating Characters
- <Sicily>Inversion Number(线段树求逆序数)
- <LeetCode> 题12: 带最小值操作的栈
- <leetcode>617. Merge Two Binary Trees
- <LeetCode><Easy>223 Rectange Area
- <LeetCode><Easy> 205 Isomorphic Strings --HashTable
- <LeetCode><Easy> 160 Intersection Of Two Listed Lists
- <leetcode> 105. Construct Binary Tree from Preorder and Inorder Traversal 重建二叉树
- <LeetCode>575. Distribute Candies
- <LeetCode><Easy> 228 Summary Ranges
- <LeetCode><Easy> 125 Valid Palindrome
- <LeetCode><Easy> 36 Valid Sodoku
- <leetcode> Permutations