题目:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
【[Golang]力扣Leetcode—剑指Offer—数组—53 - II. 0~n-1中缺失的数字(求和、二分法)】链接: 力扣Leetcode—剑指Offer—数组—53 - II. 0~n-1中缺失的数字.
示例 1:
输入: [0,1,3]示例 2:
输出: 2
输入: [0,1,2,3,4,5,6,7,9]思路:
输出: 8
- 法一:求出 0-n 的和 sum ,再求出给定数组的和,一减就是 0-n 中缺失的数字
- 法二:二分法
- 初始化: 左边界 left = 0,右边界 right = len(nums) - 1;代表闭区间 [i, j] 。
- 循环二分: 当 i ≤ j 时循环 (即当闭区间 [i, j] 为空时跳出);计算中点 mid = (i + j) / 2
- 若 nums[mid] = mid ,则 “右子数组的首位元素” 一定在闭区间 [mid + 1, j] 中,因此执行 left = mid + 1;
- 若 nums[mid] != mid ,则 “左子数组的末位元素” 一定在闭区间 [i, mid - 1] 中,因此执行 right = mid - 1;
- 返回值: 跳出时,变量 i 和 j 分别指向 “右子数组的首位元素” 和 “左子数组的末位元素” 。因此返回 i 即可。
package mainimport "fmt"func missingNumber(nums []int) int {
n := len(nums)
sum := n * (n + 1) / 2
for i := 0;
i < n;
i++ {
sum -= nums[i]
}
return sum
}func main() {
a := []int{0, 1, 2, 3, 4, 5, 6, 7, 9}
fmt.Println(missingNumber(a))
}
提交截图:
文章图片
法二代码:
package mainimport "fmt"func missingNumber(nums []int) int {
left := 0
right := len(nums) - 1
for left <= right {
mid := (left + right) / 2
if nums[mid] != mid {
//nums是有序数组,如果mid和数字不相同就在左边查找
right = mid - 1
} else {
//如果mid和数字相同,说明左边是连续的有序数组
//缺失的数字就在右边查找,left向上取整+1
left = mid + 1
}
}
return left
}func main() {
a := []int{0, 1, 2, 3, 4, 5, 6, 7, 9}
fmt.Println(missingNumber(a))
}
提交截图:
文章图片
推荐阅读
- [Golang]力扣Leetcode—剑指Offer—数组—17.打印从1到最大的n位数(遍历)
- [Golang]力扣Leetcode—中级算法—其他—两整数之和(位运算)
- [Golang]力扣Leetcode—中级算法—数学—Pow(x, n)(分治算法)
- [Golang]力扣Leetcode—中级算法—数学—Excel表列序号
- [Golang]力扣Leetcode—中级算法—数学—阶乘后的零
- [Golang]力扣Leetcode—初级算法—数学—3的幂
- 【golang】leetcode初级-删除排序数组中的重复项&买卖股票的最佳时机 II