• [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 题目总结

  • 相关阅读:
    node.js学习二---------------------同步API和异步API的区别
    node.js学习一---------------------模块的导入
    ES6函数的特性(箭头语法)
    10分钟了解Android的Handler机制
    10分钟了解Android的事件分发
    SwipeRefreshLayout,用最少的代码定制最美的上下拉刷新样式
    手把手教你React Native 实战之开山篇《一》
    Android 组件化方案探索与思考
    2018谷歌I/O开发者大会8大看点汇总 新品有哪些
    Glide高级详解—缓存与解码复用
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14224719.html
Copyright © 2020-2023  润新知