LeetCode——最大子序和

方法一【提交超时】——设计起点、终点、个数【O(n^3)】

int maxSubArray(vector<int>& nums) {
        int max = nums[0];
        for(int i = 0; i < nums.size(); ++i)
        {
            for (int j = i; j < nums.size(); ++j)
            {
                int sum = 0;
                for (int number = 0; number < j - i + 1; ++number)
                {
                    sum += nums[i+number]; 
                }
                if(sum > max)
                    max = sum;
            }
        }
        return max;

 方法二【打败3%】——设计起点、遍历所有该起点子串【O(n^2)】

 int max = nums[0];
        for(int i = 0; i < nums.size(); ++i)
        {
            int sum = 0;
            for (int number = 0; number < nums.size() - i; ++number)
            {
                sum += nums[i+number]; 
                if(sum > max)
                    max = sum;
            }
           
        }
        return max;

方法三:分治法【内涵迭代】

①直接分成左右子串:

 int algo(vector<int> &nums, int start, int end)
    {
        int Maxleft, Maxright;                                //最大左/右子串和

        if(start == end)                                      //左右端点相同
            return nums[start];
       
        int middle = (start + end) / 2;
        Maxleft  = algo(nums, start, middle);                 //迭代左子串
        Maxright = algo(nums, middle + 1 ,end);               //迭代右字串
        
       
       int MaxleftBorder = nums[middle], MaxrightBorder = nums[middle + 1];
       int leftBordersum = 0,rightBordersum = 0;
       
       
       for (int i = middle; i >=start ; i--)                   //左子串包含右端点的子串和
        {
            leftBordersum += nums[i];
            if(leftBordersum > MaxleftBorder)
                MaxleftBorder = leftBordersum;        
        }
       
       
        for (int i = middle + 1; i <= end ; i++)                //右子串包含左端点的子串和
        {
            rightBordersum += nums[i];
            if(rightBordersum > MaxrightBorder)
                MaxrightBorder = rightBordersum;
        }
       
        int doubleborder = MaxrightBorder + MaxleftBorder;       //跨子串最大和         
       
        Maxleft  = max(doubleborder, Maxleft);
        Maxright = max(doubleborder, Maxright);
        return max(Maxright, Maxleft);
    }
    
    
    
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0)
             return 0;
        else 
            return algo(nums, 0, nums.size()-1);
    }

②分成  中点  和左右子串

 int algo(vector<int> &nums, int start, int end)
    {
        int Maxleft, Maxright;
        
       if(start  > end)
           return INT_MIN;   // 此处不是返回0,比如{-2,-1},分治以后变为左中右n{},-1,{-2}三部分。左半部分{}应返回INT_MIN
        
        if(start == end)
            return nums[start];
       
        int middle = (start + end) / 2;
        Maxleft  = algo(nums, start, middle - 1);
        Maxright = algo(nums, middle + 1 ,end);
        
       
       int MaxleftBorder = nums[middle], MaxrightBorder = nums[middle];
       int leftBordersum = 0,rightBordersum = 0;
       
       
       for (int i = middle; i >=start ; i--)
        {
            leftBordersum += nums[i];
            if(leftBordersum > MaxleftBorder)
                MaxleftBorder = leftBordersum;        
        }
       
       
        for (int i = middle; i <= end ; i++)
        {
            rightBordersum += nums[i];
            if(rightBordersum > MaxrightBorder)
                MaxrightBorder = rightBordersum;
        }
       
        int doubleborder = MaxrightBorder + MaxleftBorder - nums[middle];
       
        Maxleft  = max(doubleborder, Maxleft);
        Maxright = max(doubleborder, Maxright);
        return max(Maxright, Maxleft);
    }
    
    
    
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0)
             return 0;
        else 
            return algo(nums, 0, nums.size()-1);
    }

方法四:动态规划 

图片内容转自,详见原作者:https://www.cnblogs.com/coderJiebao/p/Algorithmofnotes27.html

 int maxSubArray(vector<int>& nums) {
        int len=nums.size();
        if(len==0) return 0;
        if(len==1) return nums[0];
        vector<int> dp(len,0);
        dp[0] = nums[0];
        int max_num = dp[0];
        for (int i = 1; i< nums.size(); ++i)
        {
          if(dp[i-1]>0)
                dp[i]=dp[i-1]+nums[i];
          else 
                dp[i]=nums[i];
            max_num = max(dp[i], max_num);
        }
        
        return max_num;
    }

猜你喜欢

转载自blog.csdn.net/goldcarpenter/article/details/82924734