JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-09-28
目录

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

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

给你一个整数数组 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 位整数范围内。

# 思路

暴力解法

# 解法

class Solution {
    public int maxValueAfterReverse(int[] nums) {
        //先考虑的暴力解法。
        //i与j的子数组翻转,只有两项值发生了变化
        //……nums[i-1] nums[i]…… nums[j] nums[j+1]…… 
        //变的是abs(nums[i-1]-nums[i])+abs(nums[j]-nums[j+1])
        //变成了abs(nums[i-1]-nums[j])+abs(nums[i]-nums[j+1])
        //只翻转一次,相当于在初始数组的基础上,仅仅改变了上面两项
        int count=0;
        for(int i=0;i<nums.length-1;i++){
            count+=Math.abs(nums[i]-nums[i+1]);
        }
        int chushi=count;
        /*超时,看来o(n^2)不行,那就换个思路
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
                if(i==0&&j==nums.length-1)continue;
                else if(i==0&&j!=nums.length-1){
                    count=Math.max(count,chushi-Math.abs(nums[j]-nums[j+1])+Math.abs(nums[i]-nums[j+1]));
                }
                else if(j==nums.length-1&&i!=0){
                    count=Math.max(count,chushi-Math.abs(nums[i-1]-nums[i])+Math.abs(nums[i-1]-nums[j]));
                }
                else{
                    count=Math.max(count,chushi-Math.abs(nums[i-1]-nums[i])-Math.abs(nums[j]-nums[j+1])
                                              +Math.abs(nums[i-1]-nums[j])+Math.abs(nums[i]-nums[j+1]));
                }
            }
        }*/
        //绝对值的定义其实是数轴上两个点距离,
        //从abs(nums[i-1]-nums[i])+abs(nums[j]-nums[j+1])到abs(nums[i-1]-nums[j])+abs(nums[i]-nums[j+1])转化为距离
        //假设四个点为abcd,之前为(a,b)(c,d)
        //其中a=min(nums[i],nums[i-1]),b=max(nums[i],nums[i-1]),cd类似
        //之后可能变成(a,d)(b,c)或者(a,c)(b,d)
        //[1]如果之前的两个区间没有交集,不管是(a,d)(b,c)还是(a,c)(b,d),距离的增加量&=2*(区间距离差)
        //[2]如果之前的两个区间有交集,距离的变化不会增加:可能不变,可能减少。画个数轴图很清晰。
        for(int i=0;i<nums.length-1;i++){
            count=Math.max(count,chushi-Math.abs(nums[i]-nums[i+1])+Math.abs(nums[0]-nums[i+1]));
            count=Math.max(count,chushi-Math.abs(nums[i+1]-nums[i])+Math.abs(nums[i]-nums[nums.length-1]));
        }
        int small_max=Integer.MIN_VALUE;
        int big_min=Integer.MAX_VALUE;
        for(int i=1;i<nums.length;i++){
            small_max=Math.max(small_max,Math.min(nums[i],nums[i-1]));
            big_min=Math.min(big_min,Math.max(nums[i],nums[i-1]));
        }
        return Math.max(count,chushi+2*(small_max-big_min));     
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式