|
| 1 | +package com.fishercoder.solutions; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.List; |
| 5 | + |
| 6 | +/** |
| 7 | + * 330. Patching Array |
| 8 | + * |
| 9 | + * Given a sorted positive integer array nums and an integer n, |
| 10 | + * add/patch elements to the array such that any number in range [1, n] |
| 11 | + * inclusive can be formed by the sum of some elements in the array. Return the minimum number of patches required. |
| 12 | +
|
| 13 | + Example 1: |
| 14 | + nums = [1, 3], n = 6 |
| 15 | + Return 1. |
| 16 | +
|
| 17 | + Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4. |
| 18 | + Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3]. |
| 19 | + Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6]. |
| 20 | + So we only need 1 patch. |
| 21 | +
|
| 22 | + Example 2: |
| 23 | + nums = [1, 5, 10], n = 20 |
| 24 | + Return 2. |
| 25 | + The two patches can be [2, 4]. |
| 26 | +
|
| 27 | + Example 3: |
| 28 | + nums = [1, 2, 2], n = 5 |
| 29 | + Return 0. |
| 30 | + */ |
| 31 | +public class _330 { |
| 32 | + |
| 33 | + /**credit: https://leetcode.com/articles/patching-array/ and https://discuss.leetcode.com/topic/35494/solution-explanation/2 |
| 34 | + * |
| 35 | + * Let miss be the smallest sum in [0,n] that we might be missing. |
| 36 | + * Meaning we already know we can build all sums in [0,miss). |
| 37 | + * Then if we have a number num <= miss in the given array, |
| 38 | + * we can add it to those smaller sums to build all sums in [0,miss+num). |
| 39 | + * If we don't, then we must add such a number to the array, |
| 40 | + * and it's best to add miss itself, to maximize the reach. |
| 41 | +
|
| 42 | + Example: Let's say the input is nums = [1, 2, 4, 13, 43] and n = 100. |
| 43 | + We need to ensure that all sums in the range [1,100] are possible. |
| 44 | + Using the given numbers 1, 2 and 4, we can already build all sums from 0 to 7, i.e., the range [0,8). |
| 45 | + But we can't build the sum 8, and the next given number (13) is too large. |
| 46 | + So we insert 8 into the array. Then we can build all sums in [0,16). |
| 47 | + Do we need to insert 16 into the array? No! We can already build the sum 3, |
| 48 | + and adding the given 13 gives us sum 16. |
| 49 | + We can also add the 13 to the other sums, extending our range to [0,29). |
| 50 | + And so on. The given 43 is too large to help with sum 29, so we must insert 29 into our array. |
| 51 | + This extends our range to [0,58). |
| 52 | + But then the 43 becomes useful and expands our range to [0,101). |
| 53 | + At which point we're done.*/ |
| 54 | + |
| 55 | + public int minPatches(int[] nums, int n) { |
| 56 | + long misses = 1;//use long to avoid integer addition overflow |
| 57 | + int patches = 0; |
| 58 | + int i = 0; |
| 59 | + while (misses <= n) { |
| 60 | + if (i < nums.length && nums[i] <= misses) { //miss is covered |
| 61 | + misses += nums[i++]; |
| 62 | + } else { //patch miss to the array |
| 63 | + misses += misses; |
| 64 | + patches++;//increase the answer |
| 65 | + } |
| 66 | + } |
| 67 | + return patches; |
| 68 | + } |
| 69 | + |
| 70 | + public List<Integer> findPatches(int[] nums, int n) { |
| 71 | + long misses = 1;//use long to avoid integer addition overflow |
| 72 | + List<Integer> patches = new ArrayList<>(); |
| 73 | + int i = 0; |
| 74 | + while (misses <= n) { |
| 75 | + if (i < nums.length && nums[i] <= misses) { //miss is covered |
| 76 | + misses += nums[i++]; |
| 77 | + } else { //patch miss to the array |
| 78 | + patches.add((int) misses);//increase the answer |
| 79 | + misses += misses; |
| 80 | + } |
| 81 | + } |
| 82 | + return patches; |
| 83 | + } |
| 84 | + |
| 85 | +} |
0 commit comments