牛客堂刷题(常见面试题精讲)之左右最大值之差

来源:互联网 发布:大数据与信息安全论文 编辑:程序博客网 时间:2024/06/07 10:59

题目 

最大的 leftMax 与 rightMax 之差的绝对值
给定一个长度为N(N>1)的整型数组arr,可以划分成左右两个部分,左部分arr[0..K],右部分arr[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?
例如[2,7,3,1,1],当左部分为[2,7],右部分为[3,1,1]时,左部分中的最大值减去右部分最大值的绝对值为4。当左部分为[2,7,3],右部分为[1,1]时,左部分中的最大值减去右部分最大值的绝对值为6。还有很多划分方案,但最终返回6。

思路

方法有三,我们来逐一破解。
1、最笨的方法,遍历每个元素,按照每个进行分割,然后分别找出左侧和右侧的最大值,留下最大的差值。
毋庸置疑,时间复杂度O(n2),代码也就不演示了。

 2、我们可以用空间换时间,将时间复杂度降低为O(n),空间复杂度升为O(n)。
我们可以先对数组进行预处理,预先计算出0~i之间的最大值存入数组,再计算出i~N-1的最大值存入数组。
例如: 2 7 3 1 1,从0~~i(从左至右)最大值依次为 2 7 7 7 7,存入left数组,然后i~~N-1(从右至左)的最大值依次为 7  7  3  1  1,存入right数组,此时我们仅仅需要判断按照每一个分割时,两个最大值相减,哪个最大即可。

代码

 
public static int method_2(int [] arr){ int [] left = new int[arr.length]; int [] right = new int[arr.length];  int leftMax=arr[0]; int rightMax=arr[arr.length-1]; for(int i=0;i<arr.length;i++) { leftMax=Math.max(leftMax, arr[i]); left[i]=leftMax; } for(int i=arr.length-1;i>=0;i--) { rightMax=Math.max(rightMax, arr[i]); right[i]=rightMax; } for(int i=0;i<left.length;i++) System.out.print(left[i]+" ");  System.out.println(); for(int i=0;i<right.length;i++) System.out.print(right[i]+" "); int max=Integer.MIN_VALUE; for(int i=0;i<arr.length-1;i++) { max=Math.max(Math.abs(left[i]-right[i+1]),max); }return max;}


3、空间换时间固然不错,但是我们换个角度想一想。无论怎么分,最大值要么早左边要么在右边,而且最大值永远是被减数。假设最大值在左边,那么我们的任务就是将右侧的最大值选择的尽可能小,那么就会只有一种情况,那就是当只包含最右边的元素时,同理当最大值在右边,那么另一个就是只包含最左侧的,类似例子 2  3  7 1 6,最大值是7,包含2 和包含2 3的效果不一样。所以我们还要做的是判断左边的和右边的哪个和最大值相减后获得的结果最小,那么就按照那种分割方法。

代码

public static int method_3(int [] arr){int max=Integer.MIN_VALUE;for(int i=0;i<arr.length;i++){if(arr[i]>max) max=arr[i];}return Math.max(max-arr[0], max-arr[arr.length-1]); }



0 0