leetcode 53.Maximum Subarray

分治法

//lSum表示[left,right]内以left为左端点的最大子段和
//rSum表示[left,right]内以right为右端点的最大字段和
//iSum表示[left,right]的区间和
int divide_conquer(int* nums,int left,int right,int *lSum,int *rSum,int *iSum){
    int maxSum;//表示[left,right]内的最大字段和
    if(left == right){
        *lSum = nums[left];
        *rSum = nums[left];
        *iSum = nums[left];
        maxSum = nums[left];
        return maxSum;
    }

    int mid = (left+right)/2;
    int lSumL,rSumL,iSumL;
    int maxSumL = divide_conquer(nums,left,mid,&lSumL,&rSumL,&iSumL);
    int lSumR,rSumR,iSumR;
    int maxSumR = divide_conquer(nums,mid+1,right,&lSumR,&rSumR,&iSumR);
    *iSum = iSumL + iSumR;
    *lSum = lSumL > (iSumL + lSumR) ? lSumL:(iSumL + lSumR);
    *rSum = rSumR > (iSumR + rSumL) ? rSumR:(iSumR + rSumL);
    maxSum = maxSumL > maxSumR ? maxSumL: maxSumR;
    if(maxSum < rSumL+lSumR)
        maxSum = rSumL+lSumR;
    return maxSum;
}

int maxSubArray(int* nums, int numsSize) {
    int lSum,rSum,iSum;
    return divide_conquer(nums,0,numsSize-1,&lSum,&rSum,&iSum);
}

动态规划

第一版

int maxSubArray(int* nums, int numsSize) {
    if(numsSize == 1)
        return nums[0];
    int *max_sub_sum = (int*)malloc(sizeof(int)*numsSize);
    max_sub_sum[0] = nums[0];
    int max_sum = nums[0];
    for(int i = 1;i < numsSize;i++){
        max_sub_sum[i] =  max_sub_sum[i-1] + nums[i] >= nums[i] ? 
        max_sub_sum[i-1] + nums[i]:nums[i];
        if(max_sub_sum[i] > max_sum)
            max_sum = max_sub_sum[i];
    }
    free(max_sub_sum);
    return max_sum;
}

分析发现,numsSize等于1的情况不用单独考虑,后面的逻辑可以涵盖这种情况:

int maxSubArray(int* nums, int numsSize) {
    int *max_sub_sum = (int*)malloc(sizeof(int)*numsSize);
    max_sub_sum[0] = nums[0];
    int max_sum = nums[0];
    for(int i = 1;i < numsSize;i++){
        max_sub_sum[i] =  max_sub_sum[i-1] + nums[i] >= nums[i] ? 
        max_sub_sum[i-1] + nums[i]:nums[i];
        if(max_sub_sum[i] > max_sum)
            max_sum = max_sub_sum[i];
    }
    free(max_sub_sum);
    return max_sum;
}

进一步分析,发现求max_sub_sum[i]的时候,只需要用到max_sub_sum[i-1],而不需要用到max_sub_sum数组i-1前面的元素,所以可以用一个pre_max_sub_sum取代max_sub_sum数组的作用,节省内存开销。

int maxSubArray(int* nums, int numsSize) {
    int pre_max_sub_sum = nums[0];
    int max_sum = nums[0];
    for(int i = 1;i < numsSize;i++){
        pre_max_sub_sum =  pre_max_sub_sum + nums[i] >= nums[i] ? 
        pre_max_sub_sum + nums[i]:nums[i];
        if(pre_max_sub_sum > max_sum)
            max_sum = pre_max_sub_sum;
    }
    return max_sum;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值