首页 > 其他分享 >[LeetCode] 1330. Reverse Subarray To Maximize Array Value 翻转子数组得到最大的数组值

[LeetCode] 1330. Reverse Subarray To Maximize Array Value 翻转子数组得到最大的数组值

时间:2023-02-14 11:22:48浏览次数:79  
标签:Reverse nums max min 1330 数组 array 翻转


You are given an integer array nums. The value of this array is defined as the sum of |nums[i] - nums[i + 1]| for all 0 <= i < nums.length - 1.

You are allowed to select any subarray of the given array and reverse it. You can perform this operation only once.

Find maximum possible value of the final array.

Example 1:

Input: nums = [2,3,1,5,4]
Output: 10
Explanation: By reversing the subarray [3,1,5] the array becomes [2,5,1,3,4] whose value is 10.

Example 2:

Input: nums = [2,4,9,24,2,1,10]
Output: 68

Constraints:

  • 1 <= nums.length <= 3 * 10^4
  • -10^5 <= nums[i] <= 10^5

这道题定义了一种数组值的计算方法,将每个数字和其右边一个数字的差的绝对值算出来,并加起来。现在说允许翻转任意一个子数组一次,让求出最大的数组值。就拿题目中的例子1来分析,如不翻转子数组的话,数组值的计算应为 1+2+4+1=8,若将子数组 [3,1,5] 翻转,得到新数组为 [2,5,1,3,4],则数组值的计算为 3+4+2+1=10,这个是最大的,翻转其他任何子数组都无法超过这个值。题意搞懂了,下面就要来分析了,翻转子数组会对数组值造成什么影响,影响的是要翻转的边缘上的数字,我们让 a=2, b=3, c=5, d=4,那么原本是a和b,c和d之间相减,翻转之后就变成了a和c,b和d之间相减了,它们之间一定要存在某些关系,才能使得翻转后的数组值变大,对于下面这种情况,可以发现 max(a, b) < min(c, d),这样交换之后的数组值是增加的:

2 | 3 1 5 | 4
a   b   c   d

对于如下这种情况,可以发现 max(a, b) = min(c, d),这样交换之后的数组值是保持不变的:

2 | 3 1 5 | 3
a   b   c   d

对于如下这种情况,可以发现 max(a, b) > min(c, d),这样交换之后的数组值是减少的:

4 | 3 1 5 | 3
a   b   c   d

综上所述,需要找到第一种情况,即 max(a, b) < min(c, d)。为了使其增幅最大,需要使得 max(a, b) 尽可能小,使得 min(c, d) 尽可能大,这样才能使得数组的增幅最大。于是只要遍历所有相邻的两个数字,分别计算出 minMax 和 maxMin 即可,而数组值的增幅其实就是 (maxMin - minMax)*2

这里还需要考虑两种特殊情况,即翻转的子数组是从 nums[0] 其实的,或者是到 nums[n-1] 结束的,这样a活着d就不存在了。这两种 corner case 可以单独计算一下即可,参见代码如下:


class Solution {
public:
    int maxValueAfterReverse(vector<int>& nums) {
        int total = 0, res = 0, minMax = INT_MAX, maxMin = INT_MIN, n = nums.size();
        for (int i = 0; i < n - 1; ++i) {
            int diff = abs(nums[i] - nums[i + 1]);
            total += diff;
            res = max(res, abs(nums[0] - nums[i + 1]) - diff);
            res = max(res, abs(nums[n - 1] - nums[i]) - diff);
            minMax = min(minMax, max(nums[i], nums[i + 1]));
            maxMin = max(maxMin, min(nums[i], nums[i + 1]));
        }
        return total + max(res, (maxMin - minMax) * 2);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1330


参考资料:

https://leetcode.com/problems/reverse-subarray-to-maximize-array-value/

https://leetcode.com/problems/reverse-subarray-to-maximize-array-value/solutions/489882/o-n-solution-with-explanation/

https://leetcode.com/problems/reverse-subarray-to-maximize-array-value/solutions/489743/java-c-python-one-pass-o-1-space/


LeetCode All in One 题目讲解汇总(持续更新中...)

标签:Reverse,nums,max,min,1330,数组,array,翻转
From: https://www.cnblogs.com/grandyang/p/17118989.html

相关文章

  • 数组中找出只出现一次的两个数字
    问题:剑指Offer56-I.数组中数字出现的次数-力扣(LeetCode)该问题巧妙地利用了异或运算的性质,两个相同的数字相异或为0,遍历完所有的数字后,只剩下两个不相同的数字的异......
  • C经典 关于一维数组指针
    说明:1)一维数组指针表示方法int*p=a而非int*p=&a也可int*p=&a[0]表示2)p+1或a+1表示的是指向下一个地址#include<stdio.h>intmain(intargc,const......
  • C经典 一维数组指针解析
    #include<stdio.h>intmain(intargc,constchar*argv[]){//inta[]={1,2,3,4};int*pa[]={&a[0],&a[1],&a[2],&a[3]};printf("*pa[0]=%d\n",*pa......
  • 记录--数组去重的五种方法
    前言您或许会疑惑,网上那么多去重方法,这篇文章还有什么意义?别着急,这篇文章只节选了简单的,好玩的,古老的,有实际讲解意义的去重方法,除了去重的实现以外,我还将和您分享这其中......
  • php 常用数组方法
    array_shift() 函数用于删除数组中的第一个元素,并返回被删除的元素。array_pop()函数删除数组中的最后一个元素。array_unique()函数用于移除数组中重复的值。如果两......
  • 算法题——截断数组
    题目:截断数组要求将数组分成三个非空子数组,并且三个子数组内元素和相等,所以该数组最少要有3个元素,另外假设数组所有元素和为x,那三个子数组的元素和都为x/3,因此数组元素......
  • 【LeeCode】724. 寻找数组的中心索引
    【题目描述】给你一个整数数组 ​​nums​​ ,请计算数组的 中心下标 。数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。如果中心下......
  • 一维数组与二维数组———详细解读及一些注意事项
    一维数组一维数组的创建及初始化所谓数组,就是同一种元素的集合。一维数组的表达式为:数组元素类型+数组名+[常量表达式];#include<stdio.h>intmain(){//元素类型为int......
  • 数组的排序和查找
    1.数组156注意数组知识点double[]hens={3,5,1,3.4,2,50};1.double[]表示是double类型的数组,数组名hens2.{3,5,1,3.4,2,50}表示数组的值/元素,依次表示数......
  • *(*(p + 2) + 1) 二维数组指针位移
    ......