给定一个长度为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
//首先找到最大值以及最大值所在的位置pos: //1.如果pos=0,那么最大差值肯定是A[[0]-A[n-1],因为左部分最大值必然是A[0], //右部分必然要包含A[n-1],那么右部分最大值只会>=A[n-1] //2.如果pos=n-1,那么最大差值肯定是A[n-1]-A[0],道理和1一样 //3.如果pos是在中间位置,那么就是取(A[pos] - A[0]) 和(A[pos] - A[n-1])中最大的一个。 /***/ class MaxGap{ public: int findMaxGap(vector<int> A, int n) { // write code here int max = 0; int pos = 0; for(int i = 0; i < n; i++) if(max < A[i]){ max = A[i]; pos = i; } if(pos == 0) return A[0] - A[n-1]; if(pos == n-1) return A[n-1] - A[0]; int left = (A[pos] - A[0]); int right = (A[pos] - A[n-1]); return left > right ? left: right; } };
我自己想出了一个解法,空间复杂度是3×n,时间复杂度是O(3
×n)。看了看别人写的题解,空间复杂度还可以有个小小的优化。
public int findMaxGap(int[] A, int n) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < A.length; i++) {
if (max < A[i]) max = A[i];
}
return max - Math.min(A[0], A[n - 1]);
}
//简单说一下,不用开辟额外的空间,直接在本数组操作即可 //用三个指针就可以。一个指向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; }
class MaxGap { public: int findMaxGap(vector<int> A, int n) { // write code here vector<int> mxL(n,0);//记录i位左侧最大值 vector<int> mxR(n,0);//记录i位右侧最大值 int ma=INT_MIN; for(int i=0;i<n;i++){//左侧 if(i==0)mxL[i]=A[i]; else mxL[i]=max(A[i],mxL[i-1]); } for(int i=n-1;i>=0;i--){//右侧 if(i==n-1)mxR[i]=A[i]; else mxR[i]=max(A[i],mxR[i+1]); } int res=INT_MIN; for(int i=0;i<n-1;i++){//求差 res=max(res,abs(mxL[i]-mxR[i+1])); } return res; } };
#include <iostream> #include <vector> using namespace std; class MaxGap { public: int findMaxGap(vector<int> A, int n) { // write code here int max=A[0]; for(int i=1;i<n;i++){ if(A[i]>max) max=A[i]; } return max-A[0]>max-A[n-1]?max-A[0]:max-A[n-1]; } }; /* * 测试代码 */ int main(){ MaxGap a=MaxGap(); int b[]={2,7,3,1,1}; int lenB=sizeof(b)/sizeof(int); vector<int> c(b,b+lenB); cout<<a.findMaxGap(c,lenB)<<endl; }
//简单粗暴,容易理解,通俗易懂的代码: import java.util.*; public class MaxGap { public int findMaxGap(int[] A, int n) { int max1=A[0]; //定义一个最区间最大值初始为A[0] int max=Math.abs(A[0]-A[A.length-1]); for(int i=0;i<A.length;i++){ if(A[i]>max1){ max1=A[i]; } int max2=A[A.length-1]; //每次从n-1开始在右区间找最大值 for(int j=A.length-1;j>i;j--){ if(A[j]>max2){ max2=A[j]; } if(Math.abs(max1-max2)>max){ max=Math.abs(max1-max2); } } } return max; } }
import java.util.*; public class MaxGap { public int findMaxGap(int[] A, int n) { // write code here int[][] dp=new int[n][n]; for(int i=0;i<n;i++){ dp[i][i]=A[i]; } for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ dp[i][j]=Math.max(dp[i][j-1],A[j]); } } int max=0; for(int k=0;k<n-1;k++){ if(Math.abs(dp[0][k]-dp[k+1][n-1])>max){ max=Math.abs(dp[0][k]-dp[k+1][n-1]); } } return max; } }
#先遍历一遍A,存下来当前位置之前的最大值, #再遍历一遍求出最大值即可,复杂度O(n) # -*- coding:utf-8 -*- class MaxGap: def findMaxGap(self, A, n): # write code here maxNum, max_ = [], A[0] for i in A: max_ = max(max_, i) maxNum.append(max_) res, max_r = float('-inf'), A[-1] for i in range(n - 2, -1, -1): max_r = max(max_r, A[i + 1]) res = max(res, abs(maxNum[i] - max_r)) return res
虽然题目不难,可是我还是弄了好久 注意的坑是左边的数组的个数依次增加到n-2 自然右边的个数就得减少 还有就是求左边的最大值与右边的最大的差的绝对值 public static int findMaxGap(int[] A, int n) { // write code here int k = 0; int max = 0, sub = 0; for (k = 0; k <= n - 2; k++) { int q = 0,r = 0; int[] left = new int[k+1]; int[] right = new int[n-k-1]; for (int i = 0; i < A.Length; i++) { if (i > k) { right[r] = A[i]; r++; } else { left[q] = A[i]; q++; } } sub = left.Max() - right.Max(); if(sub<0) { sub *= -1; } if(sub>max) { max = sub; } } return max; }
最原始的办法,分别找到左边与右边的最大值,相减取绝对值。 不过本题的说法不严谨。。。有点歧义 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; }
先把寻找数组最大值单独提出来一个方法,这样看着还简单,然后把原数组A分成两个数组,分别调用方法,比较最大值即可,时间复杂度为o(n^2),不知道还有没有更简单的方法 public class MaxGap { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int A[] = { 2, 7, 3, 1, 1 }; new MaxGap().findMaxGap(A, 5); } public int findMaxGap(int[] A, int n) { // write code here int max = 0; for (int k = 0; k <= n - 2; k++) { int before[] = new int[k + 1], after[] = new int[n - k - 1]; for (int i = 0, j = k + 1; (i <= k) || (j <= n - 1); i++, j++) { if (i <= k) { before[i] = A[i]; } if (j <= n - 1) { after[j - k - 1] = A[j]; } } int maxParam = Math.abs(findMax(before) - findMax(after)); max = Math.max(maxParam, max); } System.out.println(max); return max; } public int findMax(int A[]) { int max = 0; if (A.length == 1) { return A[0]; } for (int i = 0; i < A.length - 1; i++) { if (A[i] - A[i + 1] > 0) { max = A[i]; A[i + 1] = A[i]; } else { max = A[i + 1]; } } return max; } }
class MaxGap { public: int findMaxGap(vector<int> A, int n) { // write code here int s=0,max_left=0,max_right=0; int i,k,j; for(k=0;k<=n-2;k++) { max_left=A[0]; max_right=A[k+1]; for(i=0;i<=k;i++)//求左边数组的最大值 { if(A[i]>max_left) max_left=A[i]; } for(j=k+1;j<n;j++)//求右边数组的最大值 { if(A[j]>max_right) max_right=A[j]; } if(s<abs(max_right-max_left)) s=abs(max_left-max_right); } return s;//输出最大绝对值 } };