思路一: 貪心法
-
用sum記錄從前往後掃過的最大的連續子數組的和;
-
用curSum記錄某元素前面緊挨的數組的和;
- 如果curSum小於0;說明該元素前面的子數組的和,都結果有負影響,將curSum更新爲nums[i];
4)如果curSum大於0,就把curSum更新爲 curSum+nums[i];
- 如果curSum小於0;說明該元素前面的子數組的和,都結果有負影響,將curSum更新爲nums[i];
-
判斷全局的Sum和curSum大小,更新全局的Sum;
- 時間複雜度 O(n)
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int curSum = nums[0];
int resSum = nums[0];
for(int i = 1; i < nums.length; i++){
if(curSum < 0){
curSum = nums[i];
}else{
curSum += nums[i];
}
if(curSum > resSum){
resSum = curSum;
}
}
return resSum;
}
}
思路二: 動態規劃
- 時間: O(N);
- 空間: O(1); 優化了dp表,沒有使用格外的空間開銷記錄歷史值;
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int maxsum = nums[0];
// dp[i] 表示以nums[i]爲結尾的連續字串最大的和;
// 初始: dp[0] = nums[0];
// 轉移方程:
// 當dp[i-1] < 0. 說明dp[i-1]對dp[i]產生副作用,不如nums[i]本身對dp[i]的貢獻;所以dp[i] = nums[i];
// 當dp[i-1] > 0; dp[i] = dp[i-1] + nums[i];
for(int i = 1; i < nums.length; i++){
if (nums[i-1] < 0){
nums[i] += 0;
}else{
nums[i] += nums[i-1];
}
if (maxsum < nums[i]) maxsum = nums[i];
}
return maxsum;
}
}
- 代碼簡潔版~~~
注意Math包是在 java.lang包下!!!!!而常見的集合實在java.util下,有必要分類記一下~~
import java.lang.Math;
public class Solution {
public int FindGreatestSumOfSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int max = nums[0];
// 動態規劃
// dp[i] 表示到nums[i]截止的子串最大和
// 初始: dp[0] = nums[0];
// 轉移方程: dp[i] = dp[i-1] + nums[i] ifdp[i-1] > 0
// dp[i] = nums[i]; if dp[i-1] < 0;
// 優化: dp[i] 可以不用新建,直接在原數組上修改~
for(int i = 1; i < nums.length; i++){
nums[i] += Math.max(nums[i-1], 0);
max = Math.max(max, nums[i]);
}
return max;
}
}
思路三: 暴力法
- 時間: O(N^2)
- 空間: O(N)
import java.lang.Math;
public class Solution {
public int FindGreatestSumOfSubArray(int[] nums) {
// 數組爲空時返回的是0還是null還是new int[0]?;
if (nums.length <= 0) return 0;
// 暴力法
int[] maxres = new int[nums.length];
int maxSum = nums[0];
for(int i = 0; i < nums.length; i++){
// maxres[i]表示以nums[i]開頭的連續子串的最大和。初始值爲nums[i]
maxres[i] = nums[i];
// maxres[i]不斷連續累加後續的元素。
for(int j = i+1; j < nums.length; j++){
maxres[i] += nums[j];
// 如果加到某一元素其和小於0了。說明目前的累加和對後面的子串和有負影響。
if(maxres[i] < 0) maxres[i] = nums[j];
// 判斷目前的累加和是不是爲遍歷過的所有的累加和的最大。
if(maxres[i] > maxSum) maxSum = maxres[i];
}
}
return maxSum;
}
}