• 最大子序列和问题


    求数组的最大子序列和

    方法一

    给定了一个数组让我们求他的最大子序列和,我们最容易想到的方法就是暴力枚举的方式

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int thisMax = 0, sumMax = nums[0];
            int len = nums.size();
    
            for(int i = 0; i < len; ++i){
                thisMax = 0;
                for(int j = i; j < len; ++j){
                    thisMax += nums[j];
                    sumMax = max(sumMax, thisMax);
                }
            }
    
            return sumMax;
        }
    };
    

    上述的时间复杂度为O(N^2),当数据量很大的时候就会非常的慢

    方法二

    利用分治的方式,将数组不断的递归划分成子问题。最大的会等于左边的、右边的、跨边界的三者之一

    int getMax(int arr[], int l, int r){
        if(l >= r){
            return arr[l];
        }
    
        int mid = l + r >> 1;
        int maxLeft = getMax(arr, l, mid);
        int maxRight = getMax(arr, mid + 1, r);
    
        //因为要跨边界,所以直接从边界处扫描过去,所以下面就是从mid处一路扫描过去的最大值(这里的最大值是会和边界连续的)
        int maxLeft1 = arr[mid], thisMax = 0;
        for(int i = mid; i >= l; --i){
            thisMax += arr[i];
            maxLeft1 = max(maxLeft1, thisMax);
        }
    
        thisMax = 0; int maxRight1 = arr[mid + 1];
        for(int i = mid + 1; i <= r; ++i){
            thisMax += arr[i];
            maxRight1 = max(maxRight1, thisMax);
        }
    
        int t = maxLeft1 + maxRight1;
        return (maxLeft > maxRight? (maxLeft > t? maxLeft : t) : (maxRight > t? maxRight : t));
    }
    

    时间复杂度为:O(NlogN)

    方法三

    利用Kadane算法(也就是动态规划)
    当前面的子序列和小于0的时候就不用了舍弃掉,用也只会使得后续序列变小,重新选择起点的意思。
    每一步都进行最大值的比较,这样即使系列和没有以前的大,也会使得前面序列和的值保存了到最大值变量中。

    int getMax(int arr[], int n){
        int maxSum = arr[0];
        for(int i = 1; i < n; ++i){
            if(arr[i - 1] > 0) arr[i] += arr[i - 1];//大于0的加的有意义
            maxSum = max(maxSum, arr[i]);
        }
    
        return maxSum;
    }
    

    int getMax(int arr[], int n){
        int maxSum = arr[0], thisMax = arr[0];
        for(int i = 1; i < n; ++i){
            thisMax = max(thisMax + arr[i], arr[i]);//意思就是,如果thisMax使得arr[i]变小了,就不取他,让thisMax重新选择起点
            maxSum = max(thisMax, maxSum);
        }
    
        return maxSum;
    }
    

    上述两种是一个意思,第一个是在数组原地操作,而第二个多用了一个临时变量
    时间复杂度为:O(N),是线性的

  • 相关阅读:
    VS 文件编码
    CSS中强大的EM 弹性布局
    编辑器【updating】
    下一代Jquery模板JsRender
    HTML 特殊符号编码对照表
    ASP.NET 文摘 [updating]
    Html5/Html CSS3/css 文摘 [updating]
    在Sublime Text 2中设置任意扩展名文件的默认语法
    Delphi笔记Indy10.5.5 IdTcpServer 与 IdTcpClient Demo 服务器端
    基于silverlight的工作流编辑器
  • 原文地址:https://www.cnblogs.com/Lngstart/p/12376947.html
Copyright © 2020-2023  润新知