携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
前言
今天的题目为简单,本文主要用了两种方法解题,题目整体比较简单,能够花点时间去去思考一下更加优质的解法。
每日一题
今天的题目是 1184. 公交站间的距离,难度为简单
-
环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i + 1) % n 的车站之间的距离。
-
环线上的公交车都可以按顺时针和逆时针的方向行驶。
-
返回乘客从出发点 start 到目的地 destination 之间的最短距离。
示例 1:
输入:distance = [1,2,3,4], start = 0, destination = 1
输出:1
解释:公交站 0 和 1 之间的距离是 1 或 9,最小值是 1。
示例 2:
输入:distance = [1,2,3,4], start = 0, destination = 2
输出:3
解释:公交站 0 和 2 之间的距离是 3 或 7,最小值是 3。
示例 3:
输入:distance = [1,2,3,4], start = 0, destination = 3
输出:4
解释:公交站 0 和 3 之间的距离是 6 或 4,最小值是 4。
提示:
- 1 <= n <= 10^4
- distance.length == n
- 0 <= start, destination < n
- 0 <= distance[i] <= 10^4
题解
模拟
最傻瓜式的解法--模拟,因为题目中只有两种可能性,一种是顺时针,一种是逆时针,那么我们只要把两种方式都尝试一遍,然后对比一下两个所经过的距离。
对于如何模拟两个点之间的距离,因为只用一个题目提供的数组,会比较难去计算从头到尾,或者从尾到头的变化,所以可以考虑用两个题目的数组进行拼接
就比如拿示例一来看 distance = [1,2,3,4], start = 0, destination = 1
通过两个数组拼接,就能够把问题转化为距离最近的那个满足条件的点,比方说从第一个 0 下标开始,正序就是往后查找第一个 1 下标,反过来就是从第二个 0 下标开始往前查找 1 下标。
然后将这一过程进行两次简单的模拟就能够得到答案。
function distanceBetweenBusStops(distance: number[], start: number, destination: number): number {
let min1 = 0
let min2 = 0
let n = distance.length
for(let i = start; i < n*2 ; i++) {
let j = i%n
if(j != destination) {
min1+=distance[j]
}else {
break
}
}
for(let i = start+n; i > 0 ; i--) {
let j = i%n
if(j != destination) {
min2+=distance[(j+n-1)%n]
}else {
break
}
}
return min1>min2?min2:min1
};
一次循环
上面的方法中我们对整个数组进行了两次循环,但是可以发现一个规律,对于一个距离数组来说,一个数要嘛就是正序的,要嘛就是反序的,不会存在一个距离两个都经过或者说一个距离两个都没有用到这种情况,那么我们就可以很简单的得到最短的距离,只需要先用头到尾的距离加起来,这就是正序所用的距离,然后数组的和减去这段距离剩下的就是反序的距离
比方说上面的这个例子,那么开始到结束的距离就是 2 + 3, 那么我们只要计算出数组个数的总和减去 2 + 3 剩余的就是另一个方向需要的距离。
function distanceBetweenBusStops(distance: number[], start: number, destination: number): number {
if (start > destination) {
const t = start;
start = destination;
destination = t;
}
let sum1 = 0, sum = 0;
for (let i = 0; i < distance.length; i++) {
if (i >= start && i < destination) {
sum1 += distance[i];
}
sum += distance[i]
}
return Math.min(sum1, sum-sum1);
};