首页 > 试题广场 >

左右最值最大差

[编程题]左右最值最大差
  • 热度指数:9229 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0..K],右部分A[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?

给定整数数组A和数组的大小n,请返回题目所求的答案。

测试样例:
[2,7,3,1,1],5
返回:6
给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0..K],右部分A[K+1..N-1],K可以取值的范围是[O,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?
首先我们要明确,无论怎么划分左部分和右部分,整个数组的最大值,必然会作为左部分的最大值或者右部分的最大值,参与运算,此处我们先找出整个整形数组的最大值,记为max1。假设另外一个参与运算的最大值是max2。
lmax1-max2|=|max2-max1|,这是一定的。现在我们希望|max1-max2|最大,而因为max1是整个数组的最大值,所以必有max1>max2。所以|max1-max2|=max1-max2,此处和max1与max2的符号无关,是普适性结论。
max1已经确定,那么要使max1-max2最大,只能使max2尽可能小,而max2同时还得是它所在部分的最大值。
假设数组A有6个数,分别是x1~x6,整个数组的最大值是x4,即max1=x4。
x1 x2 x3 x4 x5 x6
无论我们将x4分在左部分还是右部分,另一部分一定是从某个端口开始的,即x1或x6,此处以将x4分在右部分为例。
此时最好的结果,就是将x1作为max2。为什么呢?
如果我们将x1,x2都划分在左部分,x3~x6划分在右部分,此时有2种情况:
a).x1>x2,此时左部分的最大值max2还是x1,对最终的结果没有任何影响;
b).xl<x2,此时左部分的最大值江山易主,变为x2,但是这违背了“max2尽可能小”的原则,所以这不是我们想要的结果。
同理,将x4分在左部分,最好的结果就是将x6作为max2。
那到底应该将x4分在哪部分呢?仍然依据“max2尽可能小”的原则,我们只需比较A[O]和A[N-1],找出其中较小的那个值作为max2即可,相应地x4自然就分在max2所在部分的另一边。
而具体到代码部分,很简单,只需找出整个数组的最大值,并减去左右两端中较小的那一个即可。

具体代码如下:
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        // write code here
        int max = A[0];
        for(int i=1; i<A.length; i++){
            if(max < A[i]){
                max = A[i];
            }
        }
        int min = A[0]>A[n-1]?A[n-1]:A[0];
        return max - min;
    }
}


编辑于 2022-12-31 18:01:28 回复(0)
暴力作答法,找出最大值和开头结尾两个值中的最小值,相减就OK了
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        int max = A[0],min;
        for (int i = 0; i < n; i++){
            if (A[i] > max){
                max = A[i];
            }
        }
        min = A[0] < A[n-1] ? A[0] : A[n-1];
        return max-min;
    }
}

发表于 2021-08-06 21:46:09 回复(0)
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
         int k =n-2;
        int MAX = 0;
        for (int i = 0; i <= k ; i++) {
            int[] num1 = new int[i+1];
            int[] num2 = new int[n-(i+1)];
            for (int j = 0; j < num1.length ; j++) {
                num1[j] = A[j];
            }
            Arrays.sort(num1);
            int maxLeft = num1[num1.length-1];
            int p =i+1;
            for (int m = 0; m < num2.length ; m++) {
                num2[m] = A[p];
                p++;
            }
            Arrays.sort(num2);
            int maxRight = num2[num2.length-1];
            if(MAX < Math.abs(maxLeft-maxRight)){
                MAX = Math.abs(maxLeft-maxRight);
            }
        }
        return MAX;
    }
}

不是很聪明的做法,批评指正
发表于 2020-07-24 20:26:48 回复(0)

基于贪心算法的思想 这两个数中有一个肯定是数组的最大值。要使得差值最大,那么另一边的最大值应尽可
能的小。 假设最大值在左边,那么对于最大值右边的数组有很多种分法,每一种分法肯定都包含数组最后一
个数字即A[n-1]。 如果不取A[n-1],取最后一个数字和最大值中间的任一数字A[i]。 若A[i]大于A[n-1],那还
不如取最后一个数字;若最A[i] 小于A[n-1], 那右半边的最大值肯定不是A[i],所以无论如何右半边取最右
端数字。 假设最大值在右边,同理左半边取最左端数字。 只需用数组最大值减去数组两端较小的那个值即
可。
//老师讲的方法觉得受益良多,分享给大家

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        int max = 0;
        for(int i = 0;i<n;i++){
            if(max<A[i]){
                max = A[i];
            }
        }
        int ans1 = max - A[0];
        int ans2 = max - A[n - 1];
        if(ans1 > ans2){
            return ans1;
        }else{
            return ans2;
        }
    }
}
发表于 2019-08-10 18:52:50 回复(0)
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        int [] leftMax = new int[n];
        int [] rightMax = new int[n];
        int Max=-9999;
        
        for(int i=0;i<n-1;i++) {
            if(i==0) leftMax[i]=A[i];
            else{
                leftMax[i]=Math.max(leftMax[i-1],A[i]);
            }
        }
        for(int j=n-1;j>=0;j--) {
            if(j==n-1) rightMax[j]=A[j];
            else{
                rightMax[j]=Math.max(A[j],rightMax[j+1]);
            }
        }
        for(int i=0;i<n-1;i++) {
            Max=Math.max(Max,Math.abs(leftMax[i]-rightMax[i+1]));
        }
        return Max;
    }
}
发表于 2019-03-05 16:04:46 回复(0)

import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        int max0 = A[0];
        int[] b = new int[n];
        b[n - 1] = A[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            b[i] = A[i] > b[i + 1] ? A[i] : b[i + 1];
        }
        int maxGap = 0;
        for (int k = 0; k < n - 1; k++) {
            if(A[k]>max0) max0=A[k];
            int gap = Math.abs(max0 - b[k + 1]);
            if(gap>maxGap) maxGap=gap;
        }
        return maxGap;
    }
}

编辑于 2018-05-10 20:31:09 回复(0)
我用的Stream,才看了两天书,不要吐槽。。
 public int findMaxGap(int[] A, int n) {
        // write code here
        HashMap<String,Integer> map = new HashMap();
        map.put("index", 0);
        map.put("max", Integer.MIN_VALUE);
        Arrays.stream(A).forEach(a->{
            if(map.get("index")<=n-2){
                int temp;
                if((temp=Math.abs(Arrays.stream(Arrays.copyOf(A, map.get("index")+1)).max().getAsInt()-Arrays.stream(Arrays.copyOfRange(A, map.get("index")+1,n)).max().getAsInt()))>map.get("max")){
                    map.put("max", Math.abs(Arrays.stream(Arrays.copyOf(A, map.get("index")+1)).max().getAsInt()-Arrays.stream(Arrays.copyOfRange(A, map.get("index")+1,n)).max().getAsInt()));
                    
                }
            }
            map.put("index", map.get("index")+1);
        });
        return map.get("max");
    }


发表于 2018-02-28 23:49:44 回复(0)
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        // write code here
        int mmax = -1;
		for(int k = 0 ; k < n -1 ; k ++){
			int maxLeft = -1;
			int maxRight = -1;
			for(int i = 0 ; i < n ; i ++){
				if(i <= k){
					maxLeft = Math.max(maxLeft,A[i]);
				}else {
					maxRight = Math.max(maxRight,A[i]);
				}
			}
			mmax = Math.max(Math.abs(maxLeft-maxRight),mmax);
		}
		return mmax;
    }
}

发表于 2017-05-25 16:26:44 回复(0)
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        // write code here
        //从左边只有A[0]开始
        int lmax = A[0];
        int rmax = Integer.MIN_VALUE;
        int gap = 0;
        for(int i=0;i<A.length-1;i++){//循环次数
            //left-->A[0]~A[i],right-->A[i+1]~A[n-1]            
            lmax = Math.max(lmax,A[i]);            
            for(int j=i+1;j<A.length;j++){
                rmax = A[j];
                rmax = Math.max(rmax,A[j]);
            }            
            gap = Math.max(gap,Math.abs(lmax-rmax));
        }
        return gap;
    }
}
为何不能完全通过?

方法二:
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        
        /*
        本题用循环来做结果没有完全作对,后来想了一下,本题无非就是两种情况:
        (1)左侧所有数组中最大值的最大值  -  右侧所有数组中的最大值的最小值(左越长越好,又越短越好)
        (2)左侧所有数组中最大值的最小值  -  右侧所有数组中的最大值的最大值(左越短越好,又越长越好)
        最后取(1)(2)中的最大的、
        对于(1):left--> A[0]~A[n-2], right-->A[n-1]
        对于(2):left--> A[0],        righ-->A[1]~A[n-1]
        */
        int max = A[0];
        for(int i=0;i<A.length;i++){
            if(max<A[i]){max=A[i];}
        }
        return max-Math.min(A[0],A[n-1]);        
    }
}

编辑于 2017-03-20 17:48:46 回复(0)
最原始的办法,分别找到左边与右边的最大值,相减取绝对值。
不过本题的说法不严谨。。。有点歧义 
public int findMaxGap(int[] A, int n)
	{
        int maxDisOfTwoGroup = Integer.MIN_VALUE;
        for(int k = 0; k <(n-1);k++)
        {
        	int maxNumberOfLeft = A[0];
            for(int i = 0; i <= k ; i++)
            {
            	if(A[i] > maxNumberOfLeft)
            		maxNumberOfLeft = A[i];
            }
            
            int maxNumberOfRight = A[k+1];
            for(int i = (k+1); i < n ;i++)
            {
            	if(A[i] > maxNumberOfRight)
            		maxNumberOfRight = A[i];
            }
            
            if((maxNumberOfLeft-maxNumberOfRight) 
            		> maxDisOfTwoGroup)
            {
            	maxDisOfTwoGroup = 
            			Math.abs(maxNumberOfLeft-maxNumberOfRight);
            }
        }
        
        System.out.println(maxDisOfTwoGroup);
        return maxDisOfTwoGroup;
    }

发表于 2016-09-04 19:34:03 回复(0)
import java.util.*;
public class MaxGap {
    public int findMaxGap(int[] A, int n) {
		int max = 0;
		for (int i = 0; i < n - 1; i ++ ) {
			int max1 = max(A, 0, i);
			int max2 = max(A, i + 1, n - 1);
			int temp = Math.abs(max1 - max2);
			max = max > temp ? max : temp;
		}
		return max;
	}
	public static int max(int[] A, int start, int end) {
		int res = 0;
		for (int i = start; i <= end; i ++ ) 
			res= res > A[i] ? res : A[i];
		return res;
	}
}

编辑于 2016-08-31 03:30:26 回复(0)
import java.util.*;

public class MaxGap {
    public int findMaxGap(int[] A, int n) {
        // write code here
        int max = 0;
        for(int i = 0;i<n;i++){
            if(A[i] > max){
                max = A[i];
            }
        }
        int min = Math.min(A[0],A[n-1]);
        return Math.abs(max - min);
    }
}

感谢楼主的思路,只要考虑最大值在哪,因为要求的是差值最大,所以找到最大值之后找到两边的最小值。
发表于 2016-08-26 10:44:03 回复(0)
//简单说一下,不用开辟额外的空间,直接在本数组操作即可
//用三个指针就可以。一个指向K,其余两个以K为分界线,分别指向开头和K+1的位置
public int findMaxGap(int[] A, int n) {
        //leftmax存放左边数组的最大值,rightmax存放右边数组的最大值
        //value存放差值,temp存放每次的最大值
        int leftmax = 0 , rightmax = 0 ,value = 0 , temp = 0;
        //以K为分界线,K每次不断移动指针
        for(int K = 0 ; K < n-1 ; K++){
            //做一个判断。如果是第一次从左到K找最大数
            //就进入for循环,如果不是第一次找最大数,
            //因为前面已经在K-1个数中找到了最大数,所以不用从新开始找
            //只需要和第K个数比较一下就可以了
            if (value != 0 && A[K] > leftmax) {
                leftmax = A[K];
            } else {
                leftmax = A[0];
                // i每次从0开始遍历到K的位置,并且返回最大值
                for (int i = 0; i <= K; i++) {
                    leftmax = A[i] > leftmax ? A[i] : leftmax;
                }
            }
            rightmax = A[K+1];
            //j从K+1处开始遍历,并且返回数组最大值
            for(int j = K+1 ;j<n ; j++){
                rightmax = A[j]>rightmax?A[j]:rightmax;
            }
            //记录差值
            value = leftmax - rightmax;
            //差值小于0,取绝对值
            value = value<0?-value:value;
            //如果当前差值比上次差值大,替换差值
            temp = value>temp?value:temp;
        }
        //返回差值
        return temp;
    }

编辑于 2016-08-25 19:59:42 回复(1)

问题信息

难度:
16条回答 23078浏览

热门推荐

通过挑战的用户

查看代码