Leetcode1144. 递减元素使数组呈锯齿状

题目:

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

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

每个偶数索引对应的元素都大于相邻的元素,即 A[0] > A[1] < A[2] > A[3] < A[4] > ...
或者,每个奇数索引对应的元素都大于相邻的元素,即 A[0] < A[1] > A[2] < A[3] > A[4] < ...
返回将数组 nums 转换为锯齿数组所需的最小操作次数。

标签:数组、贪心

提示:

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

分析:

  1. 分别利用两个判断条件,计算将数组转化成锯齿数组需要的操作次数;然后返回两个值中较小的那个;
  2. 考虑边界:索引为0的元素,只需要与索引为1的元素比较;索引为n-1的元素,只需要与索引为n-2的元素比较;
  3. 在每一次比较中,基准元素不改变,其相邻元素减小;

代码: 

class Solution:
    def movesToMakeZigzag(self, nums: list[int]) -> int:
        n = len(nums)
        if n == 1:
            return 0
        even_num, odd_num = self.check(nums, n)
        if even_num >= 0 and odd_num >= 0:
            return min(even_num, odd_num)
        elif even_num >= 0 and odd_num < 0:
            return even_num
        elif even_num < 0 and odd_num >= 0:
            return odd_num
        else:
            return -2 # 若两种判定方式均无法完成转换,返回-2表示失败

    def check(self, nums: list[int], n: int) -> int:  # 若无法完成锯齿数组的转换,则返回-1,表示转换失败
        i = 0
        ke = 2 * i
        ko = 2 * i + 1
        optne, optno = 0, 0  # 总的操作次数
        even_nums, odd_nums = nums[:], nums[:]
        while ke < n and ko <= n:
            if optne != -1 and ke < n:
                optne = self.classfy_check(even_nums, ke, n, optne)
            if optno != -1 and ko < n:
                optno = self.classfy_check(odd_nums, ko, n, optno)
            i += 1
            ke = 2 * i
            ko = 2 * i + 1
        return optne, optno

    def classfy_check(self, numl: list, k: int, n: int, optn: int) -> int:
        if k == 0:
            if numl[k] <= numl[k + 1]:
                opt_res = self.operation(numl[k], numl[k + 1])
                optn += opt_res[0]
                numl[k + 1] = opt_res[1]
            return optn
        if k + 1 == n:
            if numl[k] <= numl[k - 1]:
                opt_res = self.operation(numl[k], numl[k - 1])
                optn += opt_res[0]
                numl[k - 1] = opt_res[1]
            return optn

        if numl[k] <= numl[k + 1]:
            opt_res = self.operation(numl[k], numl[k + 1])
            optn += opt_res[0]
            numl[k + 1] = opt_res[1]
        if numl[k] <= numl[k - 1]:
            opt_res = self.operation(numl[k], numl[k - 1])
            optn += opt_res[0]
            numl[k - 1] = opt_res[1]
        return optn

    def operation(self, base: int, ngb: int) -> list[int]:  # 返回达到要求的操作次数,同时修改邻居元素的值为操作后的值
        opt = 0  # 操作次数
        while ngb >= base:
            ngb -= 1
            opt += 1
        return [opt, ngb]


test = Solution()
print(test.movesToMakeZigzag([7,4,8,9,7,7,5]))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为城w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值