1. 程式人生 > 實用技巧 >[LeetCode] 1539. Kth Missing Positive Number

[LeetCode] 1539. Kth Missing Positive Number

Given an arrayarrof positive integerssorted in astrictly increasing order, and an integerk.

Find thekthpositive integer that is missing from this array.

Example 1:

Input: arr = [2,3,4,7,11], k = 5
Output: 9
Explanation: The missing positive integers are [1,5,6,8,9,10,12,13,...]. The 5thmissing positive integer is 9.

Example 2:

Input: arr = [1,2,3,4], k = 2
Output: 6
Explanation: The missing positive integers are [5,6,7,...]. The 2nd missing positive integer is 6.

Constraints:

  • 1 <= arr.length <= 1000
  • 1 <= arr[i] <= 1000
  • 1 <= k <= 1000
  • arr[i] < arr[j]for1 <= i < j <= arr.length

第K個缺失的正整數。題意是給一個升序的陣列和一個數字K,請返回第K個缺失的正整數。

這道題有好幾種解法,我這裡都列出來。分別是暴力解,線性解和二分法。

首先是暴力解,用一個指標掃描input陣列,去看每一個位置上的數字是否是要找的數字target。一開始target = 1,意思是從1開始找,如果能在input陣列中找到每個正整數,則接著往後遍歷;但凡有一個正整數找不到,就把這個缺失的正整數加到一個list中,直到這個list的size達到K。但是也有可能list沒有到K,input陣列就遍歷完了,此時可以把缺失的整數用一個while迴圈模擬完。

時間O(n)

空間O(n)

Java實現

 1 class Solution {
 2     public int findKthPositive(int
[] arr, int k) { 3 int target = 1; 4 int i = 0; 5 List<Integer> missingOnes = new ArrayList<>(); 6 while (i < arr.length) { 7 // if the target number is found 8 if (arr[i] == target) { 9 i++; 10 target++; 11 } 12 // if it's not found 13 else { 14 missingOnes.add(target); 15 target++; 16 } 17 } 18 int size = missingOnes.size(); 19 int count = size; 20 int lastNumber = (missingOnes.size() == 0) ? arr[arr.length - 1] 21 : Math.max(arr[arr.length - 1], missingOnes.get(missingOnes.size() - 1)); 22 if (count >= k) { 23 return missingOnes.get(k - 1); 24 } else { 25 while (count < k) { 26 lastNumber++; 27 count++; 28 } 29 return lastNumber; 30 } 31 } 32 }

一個比較優化的線性解法是,因為題目給的是一個升序的正整數陣列,而且陣列理論上是從1開始。所以理想情況下,數字nums[i]和它對應的下標i的關係應該是nums[i] = i + 1。所以在掃描input陣列的時候,如果發覺數字和他對應的下標的差大於1了,則說明中間開始缺失數字了。當這個差距大於等於K的時候,則找到了第K個缺失的數字。

時間O(n)

空間O(1)

Java實現

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

二分法。因為input陣列是有序的,所以如果面試官不滿意O(n)級別的思路的話,可以試圖往二分法上靠。mid找到中點,還是跟第二種做法類似,比較當前這個index上的數字和index的差值。如果差值小於K,則往陣列的右半邊找;反之則往陣列的左半邊找。

時間O(logn)

空間O(1)

Java實現

 1 class Solution {
 2     public int findKthPositive(int[] arr, int k) {
 3         int left = 0;
 4         int right = arr.length;
 5         int mid = 0;
 6         while (left < right) {
 7             mid = left + (right - left) / 2;
 8             if (arr[mid] - mid >= k + 1) {
 9                 right = mid;
10             } else {
11                 left = mid + 1;
12             }
13         }
14         return left + k;
15     }
16 }

相關題目

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 題目總結