最大子串和、积
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; }
相关文章推荐
- 最大回文子串
- 最大公共子串
- 滑动窗口1:最大窗口子串
- 面试题整理12 求字符串括号最大深度子串
- 最大子串和的问题
- 序列元素和是k的倍数的最大子串长度
- 元素和是K的倍数的子串的最大长度
- 求取一个字符串的最大回文子串
- HDU 1003 Max Sum【最大子串和】
- 获取两个字符串中最大的相同子串
- 动态规划(4)最大连续子串问题
- 53.Maximum Subarray(最大子串和)
- 15-11-常用对象API(String类-练习3-最大相同子串)
- 比较两个字符串得到两个字符串的最大子串
- 找出两个字符串中最大公共子字符串,如"abccade"、"dgcadde"的最大子串为"cad"
- 最大连续子串
- 【华为OJ平台练习题】求最大公共子串的个数和元素
- 求最大回文子串(Manacher算法)
- 09给定任意俩组字符串S1和S2,请编程输出他们间的最大相同子串
- 算法分析---查找最大回文子串