leetcode 1144. 递减元素使数组呈锯齿状(双百)

1144、递减元素使数组呈锯齿状

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

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

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

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

示例 1:

输入:nums = [1,2,3]
输出:2
解释:我们可以把 2 递减到 0,或把 3 递减到 1。

示例 2:

输入:nums = [9,6,1,6,2]
输出:4

提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 1000

题目来源:力扣(LeetCode)
https://leetcode-cn.com/problems/decrease-elements-to-make-array-zigzag

解题思路:
该问题所指的锯齿数组要么在奇数索引为波峰,偶数索引为波谷;或者偶数索引为波峰,奇数索引为波谷。所以要处理这两种情形下的操作数并比较取小者。

解题步骤:

  1. 依次遍历数组中的每个元素;
  2. 若为偶数索引:
    1. 偶数索引项作为波峰,判断与下一项之间的大小,并保存下一项操作后的值;
    2. 奇数索引项作为波峰,判断与下一项之间的大小。
  3. 若为奇数索引:
    1. 偶数索引项作为波峰,判断与下一项之间的大小。
    2. 奇数索引项作为波峰,判断与下一项之间的大小,并保存下一项操作后的值。
  4. 比较两种波峰情况下的操作数,返回操作数小的。

代码:

// 遍历数组一次
public static int movesToMakeZigzag(int[] nums) {
    // 小标奇、偶的标志位
    boolean flag = true;
    int count1 = 0;  // 记录偶数索引为波峰的操作数
    int minuend1  = nums[1];  // 奇数索引减去操作数后的剩余值
    int count2 = 0; // 记录奇数索引为波峰的操作数
    int minuend2  = nums[0];  // 偶数索引减去操作数后的剩余值
    for (int i = 0; i < nums.length-1; i++) {
        // 下标为偶数进入
        if (flag){
            // 偶数索引作为波峰的情况
            if (nums[i]<=nums[i+1]){
                count1 += nums[i+1]-nums[i]+1;
                minuend1 = nums[i]-1;
            }else{
                minuend1 = nums[i+1];
            }
            // 奇数索引作为波峰的情况
            if(minuend2 >= nums[i+1]){
                count2 += minuend2-nums[i+1]+1;
            }
        }
        // 下标为奇数进入
        if(!flag){
            // 偶数索引作为波峰的情况
            if (minuend1 >= nums[i+1]){
                count1 += minuend1-nums[i+1]+1;
            }
            // 奇数索引作为波峰的情况
            if(nums[i] <= nums[i+1]){
                count2 += nums[i+1]-nums[i]+1;
                minuend2 = nums[i]-1;
            }else{
                minuend2 = nums[i+1];
            }
        }
        flag = !flag;
    }
    return count1>=count2 ? count2:count1;
}

欢迎大家交流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值