力扣53题(求最大子序列和、贪心算法)

53.给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

  1. 看到这个题最初的想法是分别计算所有长度的子序列的和,然后取最大的那一个,于是有了以下的代码,显然这是一种暴力解法,时间复杂度太高了,在leetcode过不了。
int calSum(int* nums, int start, int end) {
    int sum = 0;
    for (int i = start; i <= end; i++) {
        sum += nums[i];
    }
    return sum;
}

int maxSubArray(int* nums, int numsSize){
    int maxSum = INT_MIN;
    for (int len = 1; len <= numsSize; len++) {
        for (int i = 0; i <= numsSize - len; i++) {
            int sum = calSum(nums, i, i + len - 1);
            if (sum > maxSum) {
                maxSum = sum;
            }
        }
    }
    return maxSum;
}
  1. 暴力解法的第二种写法是这样的,它与第一种写法的差别在于,第一种写法在每次选定一个起点的时候,只选找一个子序列然后就改变起点了,这样其实是写得过于复杂了,而第二种写法是在每次选定一个起点后,就找所有的以该位置为起点的子序列,会省去很多第一种写法多出来的步骤。
int maxSubArray(int* nums, int numsSize){
    int maxSum = INT_MIN;
    int count = 0;
    for (int i = 0; i < numsSize; i++) { //选择某个位置作为子序列起点
        count = 0;
        for (int j = i; j < numsSize; j++) { // 计算以该位置作为起点的子序列和最大的子序列
            count += nums[j];
            maxSum = count > maxSum ? count : maxSum;
        }
    }
    return maxSum;
}
  1. 但暴力解法并不是我们重点要关注的。我们重点要关注的是如何利用贪心算法来解题,贪心算法在该题表现在哪里?我们找一个子序列需要确定一个起点,如果序列中有正数的话,那么我们选择的起点对应的数值应该是正数,如果起点对应的数值是负数的话,那么该子序列就不可能是和最大的子序列,这就是贪心所在:选择的子序列起点的符号要尽可能是正的,并且在寻找子序列的过程中,若当前子序列和为负数,则要放弃当前子序列,从下一个数开始重新计算子序列。
int maxSubArray(int* nums, int numsSize){
    int maxSum = INT_MIN; //用来记录当前出现的最大的子序列和
    int count = 0; //用来累计子序列的和
    for (int i = 0; i < numsSize; i++) {
        count += nums[i];
        if (count >= maxSum) 
            maxSum = count;
        if (count <= 0) //如果当前子序列和为负数的话,则以下一个元素作为起点重新计算子序列
            count = 0;
    }
    return maxSum;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值