[leetcode] Gas Station

本文探讨了一种解决环形路线上寻找合适的起点以确保车辆能够完成一圈旅行的问题。通过分析加油站提供的油量与行驶成本之间的关系,提出两种有效算法来确定最佳起点。

From : https://leetcode.com/problems/gas-station/#

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.


Solution 1 :

对于任意加油站 i , 汽车车内在此站的增量为 inc[i] = gas[i]-cost[i] 。

题目就是要找到inc数列中的某个位置 i ,使从这个位置开始,向右(下标增大的方向)求和,和一直非负;如果没有找到, 返回 -1。本题中,如果存在这个下标,那就是唯一的。 本质上,如果inc求和非负,求环状序列的最大子序列和的脚小的下标位置; 否则返回-1。

举例:

gas  :2   5   4   2 

cost :3   7   1   1

inc   :-1 -2   3   1

inc视为环,求和非负, 那么求到最大和子序列为 3,1, 下标为2 。

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        int len = gas.size();
        if(len == 0) return -1;
        int sum = 0, index =0, cnt =0;
        
        for(int i=0;i<len;i++) {
            gas[i] = gas[i]-cost[i];
            sum += gas[i];
        }
        if(sum < 0) return -1;
        
        // 求环的最大子序列,考虑本题在sum>=0时,只有一个位置满足条件,故只要求那个永远和非负的位置
        sum = gas[0];
        for(int i=1; i<2*len-1; i++)  {
            if(sum < 0) {
               sum = gas[i%len];
               index = i;
               cnt = 1;
            } else {
               sum += gas[i%len];
               cnt++;
            }
            if(cnt == len) break;
        }
        return index;
    }
};

推荐:

public class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        if (gas == null || gas.length == 0) {
			return -1;
		}
		int sum = 0, n = gas.length;

		for (int i = n - 1; i >= 0; --i) {
			sum += (gas[i] = gas[i] - cost[i]);
		}
		if (sum < 0) {
			return -1;
		}

		int indice = 0, find = 0;
		sum = -1;

		for (int i = 0; i < n+n-1; ++i) {
			if (sum < 0) {
				indice = i;
				sum = gas[i%n];
				find = 1;
			} else {
				sum += gas[i%n];
				++find;
			}
			if (find == n) {
				break;
			}
		}

		return indice;
    }
}



Solution 2 :

思路: 

1.假设存在这个位置,那么从这个位置开始,向右累加gas[i]-cost[i],和会一直非负。

2.那么从任意位置出发,累加这个值,当和为负,则表示起始位置没有找对,那么向前找起始位置。

3.如果和为正,那么向右做累加。如果这个位置就是那个我们要找的位置,必然会使之后的和一直为正。

4.当我们对所有位置遍历一次,和为正,那么起始位置就是答案;和为负,说明没有这样的起始位置,返回-1。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        if(gas.size() == 0) return -1;
        int start=0, end=0, left=0;
        for(int i=0, num=gas.size(), count=0; count<num; count++) {
            left += gas[i]-cost[i];
            if(left >=0) {
                end++;
                i = end;
            } else {
                start = (start+num-1)%num;
                i = start;
            }
        }
        return (left>=0)*start-(left<0);
    }
};


(Mathcad+Simulink仿真)基于扩展描述函数法的LLC谐振变换器小信号分析设计内容概要:本文围绕“基于扩展描述函数法的LLC谐振变换器小信号分析设计”展开,结合Mathcad与Simulink仿真工具,系统研究LLC谐振变换器的小信号建模方法。重点利用扩展描述函数法(Extended Describing Function Method, EDF)对LLC变换器在非线性工作条件下的动态特性进行线性化近似,建立适用于频域分析的小信号模型,并通过Simulink仿真验证模型准确性。文中详细阐述了建模理论推导过程,包括谐振腔参数计算、开关网络等效处理、工作模态分析及频响特性提取,最后通过仿真对比验证了该方法在稳定性分析与控制器设计中的有效性。; 适合人群:具备电力电子、自动控制理论基础,熟悉Matlab/Simulink和Mathcad工具,从事开关电源、DC-DC变换器或新能源变换系统研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握LLC谐振变换器的小信号建模难点与解决方案;②学习扩展描述函数法在非线性系统线性化中的应用;③实现高频LLC变换器的环路补偿与稳定性设计;④结合Mathcad进行公式推导与参数计算,利用Simulink完成动态仿真验证。; 阅读建议:建议读者结合Mathcad中的数学推导与Simulink仿真模型同步学习,重点关注EDF法的假设条件与适用范围,动手复现建模步骤和频域分析过程,以深入理解LLC变换器的小信号行为及其在实际控制系统设计中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值