LeetCode 题解工作台

翻转子数组得到最大的数组值

给你一个整数数组 nums 。「数组值」定义为所有满足 0 的 |nums[i]-nums[i+1]| 的和。 你可以选择给定数组的任意子数组,并将该子数组翻转。但你只能执行这个操作 一次 。 请你找到可行的最大 数组值 。 示例 1: 输入: nums = [2,3,1,5,4] 输出: 10 解…

category

3

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 贪心·invariant

bolt

答案摘要

根据题目描述,我们需要求出:在翻转一次子数组的情况下,数组值 $\sum_{i=0}^{n-2} |a_i - a_{i+1}|$ 的最大值。 接下来,我们分以下几种情况讨论:

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 贪心·invariant 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个整数数组 nums 。「数组值」定义为所有满足 0 <= i < nums.length-1 的 |nums[i]-nums[i+1]| 的和。

你可以选择给定数组的任意子数组,并将该子数组翻转。但你只能执行这个操作 一次

请你找到可行的最大 数组值 

 

示例 1:

输入:nums = [2,3,1,5,4]
输出:10
解释:通过翻转子数组 [3,1,5] ,数组变成 [2,5,1,3,4] ,数组值为 10 。

示例 2:

输入:nums = [2,4,9,24,2,1,10]
输出:68

 

提示:

  • 2 <= nums.length <= 3*104
  • -105 <= nums[i] <= 105
  • 答案保证在 32 位整数范围内。
lightbulb

解题思路

方法一:分类讨论 + 枚举

根据题目描述,我们需要求出:在翻转一次子数组的情况下,数组值 i=0n2aiai+1\sum_{i=0}^{n-2} |a_i - a_{i+1}| 的最大值。

接下来,我们分以下几种情况讨论:

  1. 不翻转子数组
  2. 翻转子数组,且子数组“包含”第一个元素
  3. 翻转子数组,且子数组“包含”最后一个元素
  4. 翻转子数组,且子数组“不包含”第一个元素和最后一个元素

我们记不翻转子数组时的数组值为 ss,此时有 s=i=0n2aiai+1s = \sum_{i=0}^{n-2} |a_i - a_{i+1}|。我们可以将答案 ansans 初始化为 ss

如果翻转子数组,且子数组包含第一个元素,我们可以枚举翻转的子数组的最后一个元素 aia_i,其中 0i<n10 \leq i \lt n-1,此时有 ans=max(ans,s+a0ai+1aiai+1)ans = \max(ans, s + |a_0 - a_{i+1}| - |a_i - a_{i+1}|)

同理,如果翻转子数组,且子数组包含最后一个元素,我们可以枚举翻转的子数组的第一个元素 ai+1a_{i+1},其中 0i<n10 \leq i \lt n-1,此时有 ans=max(ans,s+an1aiaiai+1)ans = \max(ans, s + |a_{n-1} - a_i| - |a_i - a_{i+1}|)

如果翻转子数组,且子数组不包含第一个元素和最后一个元素,我们将数组任意两个相邻元素视为一个点对 (x,y)(x, y),记翻转的第一个元素为 y1y_1,其左侧相邻元素为 x1x_1;翻转的最后一个元素为 x2x_2,其右侧相邻元素为 y2y_2

此时相比较于不翻转子数组,数组值的变化量为 x1x2+y1y2x1y1x2y2|x_1 - x_2| + |y_1 - y_2| - |x_1 - y_1| - |x_2 - y_2|,其中,前两项可以表示为:

x1x2+y1y2=max{(x1+y1)(x2+y2)(x1y1)(x2y2)(x1+y1)(x2+y2)(x1y1)(x2y2)\left | x_1 - x_2 \right | + \left | y_1 - y_2 \right | = \max \begin{cases} (x_1 + y_1) - (x_2 + y_2) \\ (x_1 - y_1) - (x_2 - y_2) \\ (-x_1 + y_1) - (-x_2 + y_2) \\ (-x_1 - y_1) - (-x_2 - y_2) \end{cases}

那么数组值变化量为:

x1x2+y1y2x1y1x2y2=max{(x1+y1)x1y1((x2+y2)+x2y2)(x1y1)x1y1((x2y2)+x2y2)(x1+y1)x1y1((x2+y2)+x2y2)(x1y1)x1y1((x2y2)+x2y2)\left | x_1 - x_2 \right | + \left | y_1 - y_2 \right | - \left | x_1 - y_1 \right | - \left | x_2 - y_2 \right | = \max \begin{cases} (x_1 + y_1) - \left |x_1 - y_1 \right | - \left ( (x_2 + y_2) + \left |x_2 - y_2 \right | \right ) \\ (x_1 - y_1) - \left |x_1 - y_1 \right | - \left ( (x_2 - y_2) + \left |x_2 - y_2 \right | \right ) \\ (-x_1 + y_1) - \left |x_1 - y_1 \right | - \left ( (-x_2 + y_2) + \left |x_2 - y_2 \right | \right ) \\ (-x_1 - y_1) - \left |x_1 - y_1 \right | - \left ( (-x_2 - y_2) + \left |x_2 - y_2 \right | \right ) \end{cases}

因此,我们只要求出 k1×x+k2×yk_1 \times x + k_2 \times y 的最大值 mxmx,其中 k1,k2{1,1}k_1, k_2 \in \{-1, 1\},以及对应的 xy|x - y| 的最小值 mimi,那么数组值变化量的最大值为 mxmimx - mi。答案为 ans=max(ans,s+max(0,mxmi))ans = \max(ans, s + \max(0, mx - mi))

在代码实现上,我们定义了一个长度为 55 的数组 dirs=[1,1,1,1,1]dirs=[1, -1, -1, 1, 1],每次取数组相邻两个元素作为 k1,k2k_1, k_2 的值,这样可以覆盖 k1,k2{1,1}k_1, k_2 \in \{-1, 1\} 的所有情况。

时间复杂度 O(n)O(n),其中 nn 是数组 numsnums 的长度。空间复杂度 O(1)O(1)

相似题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution:
    def maxValueAfterReverse(self, nums: List[int]) -> int:
        ans = s = sum(abs(x - y) for x, y in pairwise(nums))
        for x, y in pairwise(nums):
            ans = max(ans, s + abs(nums[0] - y) - abs(x - y))
            ans = max(ans, s + abs(nums[-1] - x) - abs(x - y))
        for k1, k2 in pairwise((1, -1, -1, 1, 1)):
            mx, mi = -inf, inf
            for x, y in pairwise(nums):
                a = k1 * x + k2 * y
                b = abs(x - y)
                mx = max(mx, a - b)
                mi = min(mi, a + b)
            ans = max(ans, s + max(mx - mi, 0))
        return ans
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Evaluate the candidate's ability to apply greedy algorithms effectively.

  • question_mark

    Watch for the candidate's understanding of invariant validation and how to prove it's valid.

  • question_mark

    Check if the candidate optimizes the solution to handle larger inputs efficiently.

warning

常见陷阱

外企场景
  • error

    Failing to correctly calculate the value of the array before and after reversal can lead to incorrect results.

  • error

    Misunderstanding the impact of the reversed subarray on adjacent elements, leading to inefficient or incorrect solutions.

  • error

    Overcomplicating the problem by attempting brute-force methods when a greedy solution is more efficient.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Consider implementing the solution for arrays with only two elements.

  • arrow_right_alt

    Extend the problem to handle arrays with additional constraints, like larger numbers or specific patterns.

  • arrow_right_alt

    Explore ways to modify the problem so that multiple subarrays can be reversed for optimization.

help

常见问题

外企场景

翻转子数组得到最大的数组值题解:贪心·invariant | LeetCode #1330 困难