返回

从贪心角度轻松解读 2170. 使数组变成交替数组的最少操作数

后端







「这是我参与2022首次更文挑战的第40天,活动详情查看:2022首次更文挑战」

**题目** 

这是 LeetCode 上的 2170. 使数组变成交替数组的最少操作数,难度为中等。

给你一个长度为 n 的整数数组 nums 。数组中的元素可以是正数、负数或零。

一个 数组 nums 被称为 交替数组 ,如果满足下述条件:

* nums[i - 2] <= nums[i - 1] >= nums[i]
* 当 i >= 3 时,上述条件对于所有满足 1 <= i <= n - 2 的 i 都成立。
你可以对 nums 中的每个元素执行以下操作:

* 将其乘以 -1
* 将其增加 1
* 将其减少 1

你可以对每个元素执行任意次操作。

返回使数组 nums 变成交替数组需要的最少操作数。

**解题思路:贪心** 

- **性质分析** :

  - 交替数组是一个波浪形数组,其中相邻元素的符号相反(正负相间)。
  - 交替数组满足以下性质:

    - nums[i - 2] <= nums[i - 1] >= nums[i]
    - 当 i >= 3 时,上述条件对于所有满足 1 <= i <= n - 2 的 i 都成立。

- **贪心策略** :

  - 将数组中的元素依次分为三类:正数、负数和零。
  - 对于正数,如果前一个元素是负数或零,则减少该正数的值,否则增加该正数的值。
  - 对于负数,如果前一个元素是正数或零,则增加该负数的值,否则减少该负数的值。
  - 对于零,保持原值不变。

- **证明** :

  - 贪心策略保证了数组中的相邻元素的符号相反,满足了交替数组的定义。
  - 贪心策略保证了数组中的元素的符号尽可能接近于交替数组,即最大程度地满足了交替数组的性质。

**代码实现** 

```python
def minimumOperations(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    # 初始化操作数为 0
    operations = 0

    # 遍历数组
    for i in range(1, len(nums)):
        # 如果相邻元素的符号相同
        if nums[i] * nums[i - 1] > 0:
            # 如果前一个元素是正数
            if nums[i - 1] > 0:
                # 将当前元素减少 1
                nums[i] -= 1
                # 增加操作数
                operations += 1
            # 如果前一个元素是负数
            else:
                # 将当前元素增加 1
                nums[i] += 1
                # 增加操作数
                operations += 1

    # 返回操作数
    return operations

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。
  • 空间复杂度:O(1),因为我们只需要常数大小的额外空间。

总结

  • 交替数组是一个波浪形数组,其中相邻元素的符号相反(正负相间)。

  • 交替数组满足以下性质:

    • nums[i - 2] <= nums[i - 1] >= nums[i]
    • 当 i >= 3 时,上述条件对于所有满足 1 <= i <= n - 2 的 i 都成立。
  • 可以使用贪心算法将数组变成交替数组。

  • 贪心算法保证了数组中的相邻元素的符号相反,满足了交替数组的定义。

  • 贪心算法保证了数组中的元素的符号尽可能接近于交替数组,即最大程度地满足了交替数组的性质。