给定一个长度为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;//输出最大绝对值
}
};