您的位置:首页 > 其它

最大子串和、积

2017-10-27 16:55 113 查看

1、最大子串和

endMax[i]表示以第i项为结尾的子串最大和

状态转移方程:

dp[i] = max(dp[i-1]+arr[i],arr[i],dp[i-1])


代码实现:

/**
* 子串最大和
*
* @param arr
* @return
*/
static int getMaxSubStringSum(int[] arr) {
int[] end = new int[arr.length];
end[0] = arr[0];
int sum = arr[0];
int s = 0, e = 0;
for (int i = 1; i < arr.length; i++) {
int m = end[i - 1] + arr[i];
end[i] = Math.max(m, arr[i]);
if (end[i] == m) {
e = i;
} else {
s = i;
e = i;
}
sum = Math.max(end[i], sum);
}
System.out.println(s + "," + e);
return sum;
}

/**
* 减少空间复杂度,endMax数组直接用一个变量表示
*
* @param arr
* @return
*/
static int getMaxSubStringSum2(int[] arr) {
int endMax = arr[0];// 以第i项为结尾的子串最大和
int sum = arr[0];
int s = 0, e = 0;
for (int i = 1; i < arr.length; i++) {
int m = endMax + arr[i];
endMax = Math.max(m, arr[i]);
if (endMax == m) {
e = i;
} else {
s = i;
e = i;
}
sum = Math.max(endMax, sum);
}
System.out.println(s + "," + e);
return sum;
}


2、最大子串积

由于积可负负得正,正负得负,最大值可“瞬间”变为最小值,最小值可“瞬间”变为最大值,所以需要每次记录最大值和最小值

状态转移方程:

endMax[i] = max(max(endMax[i-1]*arr[i],endMin[i-1]*arr[i]),arr[i])
endMin[i] = min(min(endMax[i-1]*arr[i],endMin[i-1]*arr[i]),arr[i])


代码实现:

/**
* 子串最大积
*
* @param arr
* @return
*/
static int getMaxSubStringProduct(int[] arr) {
int[] endMax = new int[arr.length];
int[] endMin = new int[arr.length];
endMax[0] = arr[0];
endMin[0] = arr[0];
int result = arr[0];
int s = 0, e = 0;// 记录子串起始下标
for (int i = 1; i < arr.length; i++) {
int m1 = Math.max(endMax[i - 1] * arr[i], endMin[i - 1] * arr[i]);
endMax[i] = Math.max(m1, arr[i]);

// 记录下标
if (endMax[i] == m1) {
e = i;
}
if (endMax[i] == arr[i]) {
s = i;
e = i;
}

int m2 = Math.min(endMax[i - 1] * arr[i], endMin[i - 1] * arr[i]);
endMin[i] = Math.min(m2, arr[i]);
result = Math.max(endMax[i], result);
}
System.out.println(s + "," + e);
return result;
}

/**
* 减少空间复杂度,end数组直接用一个变量表示
*
* @param arr
* @return
*/
static int getMaxSubStringProduct2(int[] arr) {
int endMax = arr[0];
int endMin = arr[0];
int result = arr[0];
int s = 0, e = 0;// 记录子串起始下标
for (int i = 1; i < arr.length; i++) {
int m = Math.max(endMax * arr[i], endMin * arr[i]);
endMax = Math.max(m, arr[i]);

// 记录下标
if (endMax == m) {
e = i;
}
if (endMax == arr[i]) {
s = i;
e = i;
}

endMin = Math.min(Math.min(endMax * arr[i], endMin * arr[i]), arr[i]);
result = Math.max(endMax, result);
}
System.out.println(s + "," + e);
return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最大子串和