刷题的日常-递减元素使数组呈锯齿状

65 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 25 天,点击查看活动详情

刷题的日常-2023年2月27号

一天一题,保持脑子清爽

递减元素使数组呈锯齿状

来自leetcode的 1144 题,题意如下:

给你一个整数数组 nums,每次 操作 会从中选择一个元素并 将该元素的值减少 1。

如果符合下列情况之一,则数组 A 就是 锯齿数组:

  • 每个偶数索引对应的元素都大于相邻的元素,即 A[0] > A[1] < A[2] > A[3] < A[4] > ...
  • 或者,每个奇数索引对应的元素都大于相邻的元素,即 A[0] < A[1] > A[2] < A[3] > A[4] < ...

返回将数组 nums 转换为锯齿数组所需的最小操作次数。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出个数组
  • 要求我们对数组进行操作,每次选出一个数,对其进行减一操作。
  • 最后形成的数组要满足题目的要求
  • 返回我们需要操作的最小次数

做题思路

要求返回的是锯齿状数据,那么我们可以有两个选择。要么保证奇数部分小于左右两边的数,要么保证偶数部分小于左右两边的数。我们可以分别对进行统计,然后返回两者之间最小的那个。

步骤如下:

  • 如果数组长度小于2,直接返回即可
  • 分别统计奇数比较小 和 偶数比较小的情况
  • 对于每个数,取两边的差异值,拿最大的需要操作次数
  • 将操作次数累加
  • 返回累加结果

代码实现

代码实现如下:

public class Solution {
    public int movesToMakeZigzag(int... nums) {
        if (nums.length < 2) {
            return 0;
        }
        return Math.min(calc(nums, 0), calc(nums, 1));
    }
    private int calc(int[] nums, int start) {
        int res = 0, tmp;
        for (int i = start; i < nums.length; i += 2) {
            tmp = 0;
            if (i - 1 >= 0) {
                tmp = Math.max(nums[i] - nums[i - 1] + 1, tmp);
            }
            if (i + 1 < nums.length) {
                tmp = Math.max(nums[i] - nums[i + 1] + 1, tmp);
            }
            res += tmp;
        }
        return res;
    }
}

image.png