[LeetCode] 1060. Missing Element in Sorted Array

Given an integer array nums which is sorted in ascending order and all of its elements are unique and given also an integer k, return the kth missing number starting from the leftmost number of the array.

Example 1:

Input: nums = [4,7,9,10], k = 1
Output: 5
Explanation: The first missing number is 5.

Example 2:

Input: nums = [4,7,9,10], k = 3
Output: 8
Explanation: The missing numbers are [5,6,8,...], hence the third missing number is 8.

Example 3:

Input: nums = [1,2,4], k = 3
Output: 6
Explanation: The missing numbers are [3,5,6,7,...], hence the third missing number is 6.

Constraints:

  • 1 <= nums.length <= 5 * 104
  • 1 <= nums[i] <= 107
  • nums is sorted in ascending order, and all the elements are unique.
  • 1 <= k <= 108

Follow up: Can you find a logarithmic time complexity (i.e., O(log(n))) solution?

有序数组中的缺失元素。

给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。请你找到这个数组里第 k 个缺失的正整数。

这道题有两种思路,一种线性,一种二分法。需要注意一个 corner case,如果 K 大于数组的长度了,那么第 K 个缺失的元素是最后一个元素 + K。同时,missing number 的个数 = nums[end] - nums[start] - (end - start)。举例,4和7之间缺失2个数字 = (7 - 4) - (1 - 0)。

A = [4,7,9,10], K = 3

首先是线性的做法。因为数组是有序的且递增的,所以每次只要计算一下每两个数字之间的差值 - 1就知道是否到 K 了。

一开始 7 - 4 = 3,虽然两个数字的差值是 3,但是实际缺失的数字只有 2 个,所以要减一。如果每两个数字之间的差值小于 K,则需要将 K 减去两数字之间的差值之后,再带入下两个数字之间去比较。反之如果某两个数字之间的差值小于当前的 K,那么第 K 个缺失的数字 = nums[i - 1] + K。

时间O(n)

空间O(1)

Java实现

 1 class Solution {
 2     public int missingElement(int[] nums, int k) {
 3         for (int i = 1; i < nums.length; i++) {
 4             if (nums[i] - nums[i - 1] - 1 >= k) {
 5                 return nums[i - 1] + k;
 6             }
 7             k -= nums[i] - nums[i - 1] - 1;
 8         }
 9         return nums[nums.length - 1] + k;
10     }
11 }

 

再来是二分法。以后看到 input 是有序的,就要想想能不能往二分法上靠,以减小时间复杂度。

因为缺失数字的个数 missing = nums[end] - nums[start] - (end - start),所以如果 K > missing,也就是说如果数组中缺失的数字个数小于 K 的话,结果是 nums[end] + (k - missing)。如果是一般的情形,即缺失的数字夹在数组中间的话,那么我们就用二分法去找。这里的二分,看的是数组中间那个元素 nums[mid] 跟 nums[start] 元素之间有多少个缺失的元素,如果这个差值小于 K,说明要找的数字在数组的右半边,start = mid;反之如果 nums[mid] 跟 nums[start] 之间缺失元素的个数大于 K,则说明第 K 个缺失的数字在数组的左半边。

时间O(logn)

空间O(1)

Java实现

 1 class Solution {
 2     public int missingElement(int[] nums, int k) {
 3         int start = 0;
 4         int end = nums.length - 1;
 5         int missing = nums[end] - nums[start] - (end - start);
 6         // corner case
 7         if (k > missing) {
 8             return nums[end] + (k - missing);
 9         }
10         
11         // normal case
12         while (start + 1 < end) {
13             int mid = start + (end - start) / 2;
14             missing = nums[mid] - nums[start] - (mid - start);
15             if (missing < k) {
16                 k -= missing;
17                 start = mid;
18             } else {
19                 end = mid;
20             }
21         }
22         return nums[start] + k;
23     }
24 }

 

相关题目

410. Split Array Largest Sum

774. Minimize Max Distance to Gas Station

875. Koko Eating Bananas

1011. Capacity To Ship Packages In N Days

1060. Missing Element in Sorted Array

1231. Divide Chocolate

1283. Find the Smallest Divisor Given a Threshold

1482. Minimum Number of Days to Make m Bouquets

1539. Kth Missing Positive Number

LeetCode 题目总结

posted @ 2020-06-26 05:03  CNoodle  阅读(715)  评论(0编辑  收藏  举报