zoukankan      html  css  js  c++  java
  • LeetCode 53. Maximum Subarray

    问题链接

    LeetCode 53. Maximum Subarray

    题目解析

    求最大子数组。

    解题思路

    基本题,有多种方法可以得到答案,这里简单讨论一下。

    暴力

    双重循环遍历子数组起点和终点,再加一重循环计算和,时间复杂度为 (O(n^3)),代码就不写了,不可能会用得上的:)

    改进

    暴力的问题是重复计算,稍微改进一下,将第二层循环去掉,利用变量temp代表从当前数字开始到数组末端的最大子数组,只需要两层循环就够了,时间复杂度为 (O(n^2))

    最佳解法

    最大子数组问题的最佳解法是 (O(n))

    定义两个变量res和temp,其中res为当前最大子数组结果;temp初始值为0,每遍历一个数字num,如果此时temp大于0,这加上num使和更大,否则,令temp=num,表示原来的temp没有对结果做出贡献,抛弃才能使得和更大。当然,这个判断也可以简化成max(temp+num, num)。

    深入思考,这其实是DP的思想,不过是简单的DP,而且将dp数组优化成一个变量temp了。可参考DP solution & some thoughts。参考代码如下:

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int res = INT_MIN, temp = 0;
            int len = nums.size();
            for(int i = 0; i < len; i++)
            {
                if(temp > 0) temp += nums[i];
                else temp = nums[i];
                
                if(temp > res) res = temp;
            }
            return res;
        }
    };
    

    分治解法

    题目要求说试一试分治写法,很有趣。

    简单来讲就是每次见数组一分为二,比较(左边的最大子数组之和、右边的最大子数组之和、中间向左右两边扫描的最大子数组之和)三者得到答案。思路比较清晰,写起来也很快。

    时间复杂度为:(O(nlogn))。参考代码如下:

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            if (nums.empty()) return 0;
            return maxSub(nums, 0, (int)nums.size() - 1);
        }
        int maxSub(vector<int>& nums, int left, int right) {
            if (left >= right) return nums[left];
            
            int mid = (right + left) / 2;
            int lmax = maxSub(nums, left, mid - 1);//Left
            int rmax = maxSub(nums, mid + 1, right);//Right
            
            int mmax = nums[mid], t = mmax;
            for (int i = mid - 1; i >= left; --i) {
                t += nums[i];
                mmax = max(mmax, t);
            }
            t = mmax;
            for (int i = mid + 1; i <= right; ++i) {
                t += nums[i];
                mmax = max(mmax, t);
            }
            return max(mmax, max(lmax, rmax));//三者取最大值
        }
    };
    

    LeetCode All in One题解汇总(持续更新中...)

    本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


  • 相关阅读:
    Xamarin图表开发基础教程(4)OxyPlot框架
    搜索页面scroll下拉时候进行刷新,显示更多搜索值
    搜索功能
    父组件操作子组件中的值,将父组件的值设置给子组件
    扩展music-list.vue让列表前三名显示🏆奖杯
    Scroll的使用
    Vue-lazyload的使用
    获取歌曲的播放时长
    audio音乐播放
    歌曲播放页面的数据vuex管理
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8583651.html
Copyright © 2011-2022 走看看