LeetCode(134 加油问题)

如题
在这里插入图片描述
先来暴力解决方法,找到存油量大于消耗量的每一个站,然后进行测试,

public static int canCompleteCircuit(int[] gas, int[] cost) {
		int rest = 0;   //剩余油量
		int flag = 0;	//标志, 为 1代表当前余量大于等于0
		for(int i =0;i<gas.length;i++){
			if(gas[i]>=cost[i]) {   //遍历判断起点
				rest=gas[i]-cost[i];
				flag=1;    
				for(int l =1;l<gas.length;l++) {   //后续遍历
					if(l+i<gas.length) {    //对应正向遍历未到尾部
						rest=rest+gas[l+i]-cost[l+i];
					}else {    //对应到达尾部后遍历头部
						rest = rest+gas[l+i-gas.length]-cost[l+i-gas.length];
					}
					if(rest<0){   //出现余量不足情况 需切换起点
						flag=0;
						break;
					}
					flag=1;
				}
			}
			if(flag==1){   //当次遍历全程余量不为负  返回起点index
				return i;
			}
		}
		return -1;
	}

很显然可以实现当前目标,但是循环及判断过多,运行时间过长。是否存在优化可能。
先从此方法出发,观察发现有过多冗余运算,其最终结果仅仅与对应index上的差值有关,从此处着手优化。

	public static int canCompleteCircuit1(int[] gas, int[] cost) {
		int[]diff = new int[gas.length];
		for(int i=0;i<gas.length;i++) {
			diff[i]=gas[i]-cost[i];
		}
		int rest = 0;   //剩余油量
		int flag = 0;	//标志, 为 1代表当前余量大于等于0
		for(int i =0;i<diff.length;i++){
			if(diff[i]>0) {   //遍历判断起点
				rest=diff[i];
				flag=1;    
				for(int l =1;l<diff.length;l++) {   //后续遍历
					if(l+i<diff.length) {    //对应正向遍历未到尾部
						rest=rest+diff[l+i];
					}else {    //对应到达尾部后遍历头部
						rest = rest+diff[l+i-diff.length];
					}
					if(rest<0){   //出现余量不足情况 需切换起点
						flag=0;
						break;
					}
					flag=1;
				}
			}
			if(flag==1){   //当次遍历全程余量不为负  返回起点index
				return i;
			}
		}
		return -1;
	}

接着优化。
从题设分析出发,确认若存在题解则唯一。首先确认一点,存在可行解的前提是gas总和大于cost总和。第二点假设index处为唯一解,则可以确认index之前的cost总和减去gas总和达到最大值,

		public static int canCompleteCircuit2(int[] gas, int[] cost) {
		int sum = 0;  //总体差值,判断是否存在可行解
		int maxdiff = 0;  //gas和值减去cost和值最小处
		int maxindex = -1;  //最小处的index,取-1应对最优解为0情况
		for(int i =0;i<gas.length;i++) {
			int diff = gas[i]-cost[i];   //对应index的差值
			sum=sum+diff;
			if(sum<maxdiff) {	
				maxdiff=sum;
				maxindex = i;
			}
		}
		if(sum>=0) {   //当length大于1时 ,出发点为最大值后一位
			return maxindex+1;   
		}
		return -1;
		}

测试通过在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值