劍指offer42_連續子數組的最大和(java)

思路一: 貪心法

  1. 用sum記錄從前往後掃過的最大的連續子數組的和;

  2. 用curSum記錄某元素前面緊挨的數組的和;

    1. 如果curSum小於0;說明該元素前面的子數組的和,都結果有負影響,將curSum更新爲nums[i];
      4)如果curSum大於0,就把curSum更新爲 curSum+nums[i];
  3. 判斷全局的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;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章