【LeetCode】【每日一题】1184. 公交站间的距离

LeetCode 1184. 公交站间的距离

题目描述详见LeetCode原题目。

这道题的题目可以抽象成,给定一个环,环上有若干个结点,它们彼此相继连接,形成一个环形图。结点有距离,保存在数组 a a a当中, a = [ 1 , 2 , 3 , 4 ] a=[1, 2, 3, 4] a=[1,2,3,4]表示的是结点 a 1 → a 2 a_1 \rightarrow a_2 a1→a2之间的距离为 1 1 1, a 2 → a 3 a_2 \rightarrow a_3 a2→a3之间的距离为 2 2 2, a 3 → a 4 a_3 \rightarrow a_4 a3→a4之间的距离为 3 3 3, a 4 → a 1 a_4 \rightarrow a_1 a4→a1之间的距离为 4 4 4。注意图的连接关系是双向的,即从某个结点可以向前走也可以向后走。

现在给定一个query,它有start和destination组成,二者均对应于环形图当中的结点编号,求从 s t a r t → d e s t i n a t i o n start \rightarrow destination start→destination之间的最短距离,也就是双向距离当中的最小者。

给出这道题之后我的思路是非常明确的,先后求从 s t a r t → d e s t i n a t i o n start \rightarrow destination start→destination向前走和向后走的最短距离即可,但是在实现上遇到了坑。

参考了LeetCode C++部分的题解,豁然开朗,其中利用到了C++ numeric库当中的accumulate,我感觉非常的使用,便在此进行记录。

accumulate有四个参数,分别是迭代器的起始位置、终点位置、累加的初始值以及自定义操作函数,前三个参数是必须的,第四个由于还没有用到所以不做深究。

在最开始,如果 s t a r t start start的位置在 d e s t i n a t i o n destination destination的右侧,那么可以交换二者的位置,使得 s t a r t start start永远比 d e s t i n a t i o n destination destination小,有助于后续的问题分析,二者是等价的。

现在,答案是显而易见的,由两部分当中的较小者组成,第一部分是从 s t a r t start start直接"向右"走到 d e s t i n a t i o n destination destination的距离,而第二部分是从 s t a r t start start向相反方向(此时一定经过了编号为0的结点)走到 d e s t i n a t i o n destination destination的距离。分别对应于accumulate(distance.begin() + start, distance.begin() + destination, 0)accumulate(distance.begin(), distance.begin() + start, 0) + accumulate(distance.begin() + destination, distance.end(), 0)

经过我自己的实验发现,accumulate当中迭代器的位置也是左闭右开的,意味着第二个参数"迭代器的终点"将不会被累加,累加一直持续到"迭代器终点的前一个位置" 。这与vector容器的begin(), end()也是左闭右开是对应的,因此使用accumulate(v.begin(), v.end(), 0)可以完成对vector对象v当中元素的累加。

本题最关键的一点也就是要意识到给定的distance数组是左开右闭的,需要利用这一点来进行累加。

本题的代码实现如下:

cpp 复制代码
class Solution {
public:
    int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {
        if(start > destination) {
            swap(start, destination);
        }
        cout << accumulate(distance.begin()+start, distance.begin()+destination, 0) << endl;
        cout << accumulate(distance.begin(), distance.begin()+start, 0) + 
            accumulate(distance.begin()+destination, distance.end(), 0) << endl;
        return min(
            accumulate(distance.begin()+start, distance.begin()+destination, 0),
            accumulate(distance.begin(), distance.begin()+start, 0) + 
            accumulate(distance.begin()+destination, distance.end(), 0)
        );
    }
};

Go语言对应的实现,Go语言的实现中没有用到累加函数,而是直接使用for循环进行累加,注意处理左开右闭这条性质即可:

go 复制代码
func distanceBetweenBusStops(distance []int, start int, destination int) int {
    if start > destination { 
        start, destination = destination, start // 注意start和destination是参数, 它们已经被声明了
        // 此处不能够使用 := 进行swap, 而应该直接使用 =
    }

    ans_1, ans_2 := 0, 0
    
    for i:=0; i<len(distance); i++ {
        if start <= i && i < destination { // 处理左开右闭, 计算的是从start正向走到destination的距离
            ans_1 += distance[i]
        } else {						   // 从start反向走到destination的距离
            ans_2 += distance[i]
        }
    }

    return min(ans_1, ans_2)
}
相关推荐
CoovallyAIHub4 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP5 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo5 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo6 小时前
300:最长递增子序列
算法
CoovallyAIHub11 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub11 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js