[LeetCode] 1526. Minimum Number of Increments on Subarrays to Form a Target Array

Given an array of positive integers target and an array initial of same size with all zeros.

Return the minimum number of operations to form a target array from initial if you are allowed to do the following operation:

  • Choose any subarray from initial and increment each value by one.

The answer is guaranteed to fit within the range of a 32-bit signed integer.

Example 1:

Input: target = [1,2,3,2,1]
Output: 3
Explanation: We need at least 3 operations to form the target array from the initial array.
[0,0,0,0,0] increment 1 from index 0 to 4 (inclusive).
[1,1,1,1,1] increment 1 from index 1 to 3 (inclusive).
[1,2,2,2,1] increment 1 at index 2.
[1,2,3,2,1] target array is formed.

Example 2:

Input: target = [3,1,1,2]
Output: 4
Explanation: (initial)[0,0,0,0] -> [1,1,1,1] -> [1,1,1,2] -> [2,1,1,2] -> [3,1,1,2] (target).

Example 3:

Input: target = [3,1,5,4,2]
Output: 7
Explanation: (initial)[0,0,0,0,0] -> [1,1,1,1,1] -> [2,1,1,1,1] -> [3,1,1,1,1] 
                                  -> [3,1,2,2,2] -> [3,1,3,3,2] -> [3,1,4,4,2] -> [3,1,5,4,2] (target).

Example 4:

Input: target = [1,1,1,1]
Output: 1

Constraints:

  • 1 <= target.length <= 10^5
  • 1 <= target[i] <= 10^5

形成目标数组的子数组最少增加次数。

给你一个整数数组 target 和一个数组 initial ,initial 数组与 target  数组有同样的维度,且一开始全部为 0 。

请你返回从 initial 得到  target 的最少操作次数,每次操作需遵循以下规则:

在 initial 中选择 任意 子数组,并将子数组中每个元素增加 1 。
答案保证在 32 位有符号整数以内。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-number-of-increments-on-subarrays-to-form-a-target-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题的题意反过来理解就是给一个数组,请问你通过几次操作能把数组的所有元素修改为0。修改的规则是每次只能把数组中的最大值 - 1。

这道题我给出两种做法,其实背后都是同一种思路,类似求前缀和。对于每一个数字 target[i],我们看他与 target[i - 1] 之间的差值,每两个数字之间的差值就是全局需要操作的次数。当这个差值大于0就是操作次数;当这个差值小于0则无需计算,因为我们一开始计算过了最大值和0之间的差值了。

时间O(n)

空间O(n)

Java prefix sum实现

 1 class Solution {
 2     public int minNumberOperations(int[] target) {
 3         int res = 0;
 4         int pre = 0;
 5         for (int num : target) {
 6             res += Math.max(num - pre, 0);
 7             pre = num;
 8         }
 9         return res;
10     }
11 }

Java单调栈实现

 1 class Solution {
 2     public int minNumberOperations(int[] target) {
 3         // corner case
 4         if (target.length == 1) {
 5             return target[0];
 6         }
 7 
 8         // normal case
 9         int res = 0;
10         Stack<Integer> stack = new Stack<>();
11         stack.push(target[0]);
12         for (int i = 1; i < target.length; i++) {
13             int cur = target[i];
14             int prev = stack.peek();
15             if (cur > prev) {
16                 stack.push(cur);
17             } else if (cur == prev) {
18                 continue;
19             } else {
20                 res += stack.pop() - cur;
21                 stack.push(cur);
22             }
23         }
24         return res + stack.pop();
25     }
26 }

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14224719.html