这道题目是昨天上午在猫眼面试时遇到的,总感觉似曾相识,但是却有想不出在哪见过。当然了,这道题最终我是没有解答出来的,这会就再好好思考下怎么解决这个问题吧!
算法战五渣的我思考了一会还是没思路就不浪费时间了,还是求助于度娘。。。
然后,看到了这个老铁的博客:http://blog.csdn.net/a253664942/article/details/51051499,瞬间就明白了。下面就自己手动写下实现吧!
简单粗暴
这位老铁的方法二虽然时间复杂度高一点,却是较为直接、简单的,那就先写方法二的实现吧:
import java.util.Arrays;
/**
* Created by clearbug on 2018/2/26.
*/
public class Solution {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int[] arr = Utils.intArray(i + 1);
System.out.println("arr = " + Arrays.toString(arr) + ", maxSubSum = " + getMaxSubSum(arr));
}
}
// aNotFound404: 方法二
public static int getMaxSubSum(int[] arr) {
int currSum = 0, maxSum = 0;
for (int i = 0; i < arr.length; i++) {
currSum += arr[i];
if (currSum < 0) {
currSum = arr[i];
}
if (currSum > maxSum) {
maxSum = currSum;
}
}
return maxSum;
}
}
不过 aNotFound404: 方法二逻辑上有些看不明白,所以我自己写了个工具类来进行了下测试工作:
import java.util.Arrays;
import java.util.Random;
/**
* Created by clearbug on 2018/3/2.
*/
public class Utils {
public static void main(String[] args) {
System.out.println(Arrays.toString(intArray(3)));
System.out.println(Arrays.toString(intArray(5)));
System.out.println(Arrays.toString(intArray(7)));
}
public static int[] intArray(int len) {
int[] res = new int[len];
Random rand = new Random();
for (int i = 0; i < len; i++) {
res[i] = rand.nextInt(100) - 50;
}
return res;
}
}
然后 Solution 类 main 方法的运行结果如下:
arr = [-42], maxSubSum = 0
arr = [5, 23], maxSubSum = 28
arr = [-50, 21, -26], maxSubSum = 21
arr = [29, -25, 16, -18], maxSubSum = 29
arr = [-31, 7, 45, 11, -19], maxSubSum = 63
arr = [15, -47, 41, 12, 29, 2], maxSubSum = 84
arr = [8, -3, -3, 17, -1, -36, 12], maxSubSum = 19
arr = [-33, 48, -4, -16, -44, 20, 10, -45], maxSubSum = 30
arr = [33, 42, 49, 3, -18, 38, 19, -9, -41], maxSubSum = 166
arr = [33, 23, -2, -11, -16, 35, 16, 46, 13, 1], maxSubSum = 138
可以看到第八次测试的结果明显是错误的,应该是 48,而不是 20 + 10 = 30
好吧,这位 aNotFound404 老铁的博客就先不看了吧,免得被误导。。。
然后我又搜索到了另外一位老铁的博客,http://blog.csdn.net/wangzhiyu1980/article/details/51392500。从他的博客上来看,这道题目应该是《编程之美》这本书上的原题,看来刷算法题的话《剑指Offer》和《编程之美》这两本书还是必看的啊!
然后,zy 这位老铁说这道题的解法使用了动态规划的思想,但是我之前并不知道什么是动态规划,然后我又搜索了下动态规划是什么鬼?看了下面这两篇文章基本上有点认识了:
https://www.zhihu.com/question/23995189
http://www.sohu.com/a/153858619_466939?p=wechat
好了,现在大概是理解动态规划了。那么,怎么解决这道题目呢?好吧,想了一会我还是不知道如何使用动态规划来解决这个问题。。。直接下载了《编程之美》这本书的pdf版本来看解法吧!
解法一
import java.util.Arrays;
/**
* Created by clearbug on 2018/2/26.
*/
public class Solution {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int[] arr = Utils.intArray(i + 1);
System.out.println("arr = " + Arrays.toString(arr) + ", maxSubSum = " + maxSubSum1(arr));
}
}
/**
* 《编程之美》解法一:穷举法
*
* 时间复杂度:O(n^3)
*
* @param arr 目标数组
* @return 最大子序列和
*/
public static int maxSubSum1(int[] arr) {
int res = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; j++) {
int sum = 0;
for (int k = i; k <= j; k++) {
sum += arr[k];
}
if (sum > res) {
res = sum;
}
}
}
return res;
}
}
仔细考虑下,其实第三层循环是没有必要的,所以做一下优化:
/**
* 《编程之美》解法一:穷举法-优化版
*
* 时间复杂度:O(n^2)
*
* @param arr 目标数组
* @return 最大子序列和
*/
public static int maxSubSum1Opt(int[] arr) {
int res = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
int sum = 0;
for (int j = i; j < arr.length; j++) {
sum += arr[j];
if (sum > res) {
res = sum;
}
}
}
return res;
}
参考
http://blog.csdn.net/a253664942/article/details/51051499
https://www.zhihu.com/question/23995189
http://www.sohu.com/a/153858619_466939?p=wechat