We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
nums
|nums[i] - nums[i + 1]|
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),这样交换之后的数组值是增加的:
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
max(a, b) < min(c, d)
2 | 3 1 5 | 4 a b c d
对于如下这种情况,可以发现 max(a, b) = min(c, d),这样交换之后的数组值是保持不变的:
max(a, b) = min(c, d)
2 | 3 1 5 | 3 a b c d
对于如下这种情况,可以发现 max(a, b) > min(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。
max(a, b)
min(c, d)
(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 同步地址:
#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 题目讲解汇总(持续更新中...)
(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)
喜欢请点赞,疼爱请打赏❤️~.~
微信打赏
|
Venmo 打赏
---|---
The text was updated successfully, but these errors were encountered:
No branches or pull requests
You are given an integer array
nums
. The value of this array is defined as the sum of|nums[i] - nums[i + 1]|
for all0 <= 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)
,这样交换之后的数组值是增加的:对于如下这种情况,可以发现
max(a, b) = min(c, d)
,这样交换之后的数组值是保持不变的:对于如下这种情况,可以发现
max(a, b) > min(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 可以单独计算一下即可,参见代码如下:
Github 同步地址:
#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 题目讲解汇总(持续更新中...)
(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)
微信打赏
Venmo 打赏
---|---
The text was updated successfully, but these errors were encountered: