0
点赞
收藏
分享

微信扫一扫

代码随想录之贪心系列困难算法

千白莫 2022-05-04 阅读 82

文章目录

代码随想录之贪心系列困难算法

1.最大子序和(最大子数组和)

2.加油站

2.1暴力

func canCompleteCircuit(gas []int, cost []int) int {
	for i := 0; i < len(gas); i++ {
		//记录剩余汽油量
		rest := gas[i] - cost[i]
        //这里要rest += gas[index] - cost[index]的原因是在循环里面要继续进行相减了
		index := (i + 1) % len(gas)
		for rest > 0 && index != i {
			rest += gas[index] - cost[index]
			index = (index + 1) % len(gas)   //循环自动连接首部
		}
		//如果以i为起点跑一圈,剩余油量>=0,则说明可以
		if rest >= 0 && index == i {
			return i
		}
		

	}
	return -1
}

//一各一个起点尝试,如果跑了一圈,中途没有断油,而且最后油量大于等于0,说明这个起点是ok的。
//O(N^2)
空间复杂度:$O(n)$

image-20220309213214704

2.2贪心

func canCompleteCircuit(gas []int, cost []int) int {
	curSum := 0
	totalSum := 0
	start := 0
    //每一个加油点都要进行尝试
	for i := 0; i < len(gas); i++ {
		curSum += gas[i] - cost[i]
		totalSum += gas[i] - cost[i]
		if curSum < 0 {
			start = i+1
			curSum = 0
		}
	}
    // 因为耗油总和是大于零的,如果小于0说明怎么走都不可能跑一圈了
	if totalSum < 0 {
		return -1
	}
    
	return start//即大于等于0的情况,totalSum < 0
}
//思路:我们可以通过减小被检查的加油站数目,来降低总的时间复杂度。
那么局部最优:当前累加rest[j]的和curSum一旦小于0,起始位置至少要是j+1,因为从j开始一定不行。
全局最优:找到可以跑一圈的起始位置。
那么为什么一旦[i,j] 区间和为负数,起始位置就可以是j+1呢,j+1后面就不会出现更大的负数?
看如下图:
为什么最后还要进行一下if totalSum < 0 判断?
为什么本题解法没有体现到环形数组呢?
i不一定要
//canCompleteCircuit 时间复杂度O(N),空间复杂度O(1)

image-20220309222104015

image-20220309161931037

image-20220309161947757

举报

相关推荐

0 条评论