LeetCode 53. 最大子序和 (贪心、DP、分治)

  • 贪心
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        long long ans = -3e9,cnt = 0, his=0, n = nums.size(); 
        for(int i=0;i<n;i++){
            if(his<0){
                // 如果 以上一个数结尾的子数组的和 小于0,那就不要前面这段
                cnt = nums[i];
            }else{
                // 否则前面的那段和这个数连起来构成一段
                cnt = nums[i]+his;
            }
            ans = max(ans,cnt);
            his = cnt;
        }
        return (int)ans;
    }
};
  • DP
    DP方程:
    d p [ i ] dp[i] dp[i]表示以第i位结尾的子数组的最大和
    d p [ i ] = m a x ( d p [ i − 1 ] + n u m s [ i ] , n u m s [ i ] ) dp[i]=max(dp[i-1]+nums[i],nums[i]) dp[i]=max(dp[i1]+nums[i],nums[i])
    那么答案就是 m a x ( d p [ i ] ) , i ∈ [ 0 , n − 1 ] max(dp[i]),i\in [0,n-1] max(dp[i]),i[0,n1]
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int  n = nums.size() ,ans = -1e9;
        vector<int> dp(n+1,0);
        for(int i=1;i<=n;i++){
            dp[i] = max(dp[i-1]+nums[i-1],nums[i-1]);
            ans = max(ans,dp[i]);
        }
        return ans;
    }
};

如果进行空间的压缩之后,其实就贪心的做法。

  • 分治。
    一开始写分治解法的时候,不是特别懂,现在一写突然发现这不就是线段树的递归写法吗?
    当然线段树其实就是基于分治思想的二叉树。
    不过这里我们并没有必要真的去建立一棵线段树,毕竟是静态的数据。
    但是如果要去对区间里的值进行大量修改,然后又有大量询问,时间复杂度就高达 O ( m ∗ n ) O(m*n) O(mn),这个时候如果用线段树去维护区间信息,每次更新和查询的时间复杂度仅为 O ( l o g ( n ) ) O(log(n)) O(log(n)),整体时间复杂度: O ( n + m ∗ l o g ( n ) ) O(n+m*log(n)) O(n+mlog(n))

注意此解法的时间复杂度为: O ( n ) O(n) O(n),而不是 O ( n ∗ l o g ( n ) ) O(n*log(n)) O(nlog(n)),用二叉树的遍历来理解就很好懂。

class Solution {
public:
    struct Node{
        int s,ls,rs,ms;
        Node(int s,int ls,int rs,int ms):s(s),ls(ls),rs(rs),ms(ms){}
    };
    int maxSubArray(vector<int>& nums) {
        return dc(0,nums.size()-1,nums).ms;
    }
    Node dc(int l,int r,vector<int>& nums){
        if(l==r){
            return Node(nums[l],nums[l],nums[l],nums[l]);
        }
        int mid = l+(r-l)/2;
        Node ln = dc(l,mid,nums);
        Node rn = dc(mid+1,r,nums);
        int s = ln.s+rn.s;
        int ls = max(ln.ls,ln.s+rn.ls); 
        int rs = max(rn.rs,rn.s+ln.rs);
        int ms = max(max(ln.ms,rn.ms),ln.rs+rn.ls);
        return Node(s,ls,rs,ms);
    }
};

你可能感兴趣的:(LeetCode,#,LC分治,#,LC动态规划)