• 53. 最大子序和


    题目描述: 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
    示例:
    输入: [-2,1,-3,4,-1,2,1,-5,4],
    输出: 6
    解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
    进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

    • 动态规划or贪心:

      容易想到的实现方法,使用一个数组记录连续子序列的和,选择子序列的标准:如果上一个子序列的和与当前值相加后反而比当前值还小,那就舍弃上一个子序列,而从当前值开始一个新的子序列计算和,一次遍历,时间复杂度O(n)

    //C
    
    int maxSubArray(int* nums, int numsSize){
        if(numsSize == 1) return nums[0];
    
        int *resArr = (int *)malloc(numsSize * sizeof(int));
        int i, temp;
        resArr[0] = nums[0];
        for(i = 1; i < numsSize; i++){
            temp = (nums[i] + resArr[i - 1]);
            resArr[i] = nums[i] > temp ? nums[i] : temp;
        }
        temp = resArr[0];
        for(i = 1; i < numsSize; i++){
            if(resArr[i] > temp) temp = resArr[i];
        }
        return temp;
    }
    
    //JS
    var maxSubArray = function(nums) {
        let sumArr = [nums[0]], tmp = 0;
        for(let i = 1; i < nums.length; i++){
            tmp = sumArr[i - 1];
            sumArr.push(Math.max(nums[i], nums[i] + tmp));
        }
        return Math.max.apply(null, sumArr);
    };
    • 进一步提高空间复杂度的做法,使用变量记录最大自序和
    //JS
    
    var maxSubArray = function(nums) {
        let res = sum = nums[0];
        for(let i = 1; i < nums.length; i++){
            sum = Math.max(sum + nums[i], nums[i]);
            res = Math.max(res, sum);
        }
        return res;
    };
    • 分治算法:分成三部分,左右中,最大连续自序和要么在左部分,要么在又部分,或者是中间部分。

      以本题为例,中部计算就是向中间元素的左侧和右侧分别计算出最大的连续子序列和,相加;左右部分也是相同的递归过程,再比较三者中最大的数

    //JS
    
    var maxSubArray = function(nums) {
        //分治法
        let getSubArr = (arr, low, high) => {
            if(low == high) return arr[low];
    
            let lmax = -Number.MAX_SAFE_INTEGER,
            rmax = -Number.MAX_SAFE_INTEGER,
            mid = Math.floor((high - low) / 2) + low,
            sum = 0;
            
            let l = getSubArr(nums, low, mid),
            r = getSubArr(nums, mid + 1, high);
    
            for(let i = mid; i >= low; i--){
                sum += nums[i];
                if(sum > lmax) lmax = sum;
            }
            sum = 0;
            for(let i = mid + 1; i <= high; i++){
                sum += nums[i];
                if(sum > rmax) rmax = sum;
            }
            return Math.max(l, r, lmax + rmax);
        };
        return getSubArr(nums, 0, nums.length - 1);
    };
    

      

  • 相关阅读:
    前端开发者也可以酷酷地开发桌面程序
    手把手教你怎么搭建angular+gulp的项目(一)
    在Angular中,如果权限值是异步请求所得,如何将其设置为HTTP请求头的Authorization?
    AngularJs ng-repeat指令中怎么实现含有自定义指令的动态html
    第一篇随笔,练练手
    我参与 Seata 开源项目的一些感悟
    一次 kafka 消息堆积问题排查
    图解 Kafka 水印备份机制
    Seata 动态配置订阅与降级实现原理
    记一次 Kafka 集群线上扩容
  • 原文地址:https://www.cnblogs.com/JesseyWang/p/13086027.html
Copyright © 2020-2023  润新知