[LeetCode] 1144. Decrease Elements To Make Array Zigzag 递减元素使数组呈锯齿状


Given an array nums of integers, a move consists of choosing any element and decreasing it by 1.

An array A is a zigzag array if either:

  • Every even-indexed element is greater than adjacent elements, ie. A[0] > A[1] < A[2] > A[3] < A[4] > ...
  • OR, every odd-indexed element is greater than adjacent elements, ie. A[0] < A[1] > A[2] < A[3] > A[4] < ...

Return the minimum number of moves to transform the given array nums into a zigzag array.

Example 1:

Input: nums = [1,2,3]
Output: 2
Explanation: We can decrease 2 to 0 or 3 to 1.

Example 2:

Input: nums = [9,6,1,6,2]
Output: 4

Constraints:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000

这道题说是每次可以给数组中的任意数字减小1,现在想将数组变为之字形,就是数字大和小交替出现,有两种,一种是偶数坐标的数字均大于其相邻两个位置的数字,一种是奇数坐标的数字均大于其相邻的两个位置的数字。对于第一种情况来说,其奇数坐标位置的数字就均小于其相邻两个位置的数字,同理,对于第二种情况,其偶数坐标位置的数字就均小于其相邻两个位置的数字。这里我们可以分两种情况来统计减少次数,一种是减小所有奇数坐标上的数字,另一种是减小所有偶数坐标上的数字。减小的方法是找到相邻的两个数字中的较小那个,然后比其小1即可,即可用 nums[i] - min(left, right) + 1 来得到,若得到了个负数,说明当前数字已经比左右的数字小了,不需要再减小了,所以需要跟0比较,取较大值。这里用了一个大小为2的 res 数组,这用直接根据当前坐标i,通过 i%2 就可以更新对应的次数了,最终取二者中的较小值返回即可,参见代码如下:


class Solution {
public:
    int movesToMakeZigzag(vector<int>& nums) {
        int n = nums.size(), res[2] = {0, 0};
        for (int i = 0; i < n; ++i) {
            int left = i > 0 ? nums[i - 1] : 1001;
            int right = i < n - 1 ? nums[i + 1] : 1001;
            res[i % 2] += max(0, nums[i] - min(left, right) + 1);
        }
        return min(res[0], res[1]);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1144


类似题目:

ZigZag Conversion

Binary Tree Zigzag Level Order Traversal


参考资料:

https://leetcode.com/problems/decrease-elements-to-make-array-zigzag/

https://leetcode.com/problems/decrease-elements-to-make-array-zigzag/discuss/350576/JavaC%2B%2BPython-Easy-and-concise

https://leetcode.com/problems/decrease-elements-to-make-array-zigzag/discuss/351306/C%2B%2B-O(n)-Brute-force-Easy-to-understand-and-detailed-explanation


LeetCode All in One 题目讲解汇总(持续更新中...)

上一篇:微信公众号,统计公众平台的打赏人数和金额脚本


下一篇:在核心线程数已满的情况下如何实现阻塞队列?