剑指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;
    }
}

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