LeetCode每日一结10

11 篇文章 0 订阅
4 篇文章 0 订阅

公交线路

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用



题目

给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。

例如,路线 routes[0] = [1, 5, 7] 表示第 0 辆公交车会一直按序列 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> … 这样的车站路线行驶。
现在从 source 车站出发(初始时不在公交车上),要前往 target 车站。 期间仅可乘坐公交车。

求出 最少乘坐的公交车数量 。如果不可能到达终点车站,返回 -1 。

示例 1:

输入:routes = [[1,2,7],[3,6,7]], source = 1, target = 6
输出:2
解释:最优策略是先乘坐第一辆公交车到达车站 7 , 然后换乘第二辆公交车到车站 6 。
示例 2:

输入:routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
输出:-1

提示:

1 <= routes.length <= 500.
1 <= routes[i].length <= 105
routes[i] 中的所有值 互不相同
sum(routes[i].length) <= 105
0 <= routes[i][j] < 106
0 <= source, target < 106

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bus-routes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


提示:以下是本篇文章正文内容,下面案例可供参考

解答

代码如下(示例):

class Solution {
public:
    int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
        vector<int> getnext(int source){//获取当前车站可到达的站点
            vector<int> nextst;
            for(int i=0;i<routes.size();i++){
                for(int j=0;j<routes[i].size();j++){
                    if(source==routes[i][j]){//找到经过当前站点的公交车
                        for(int j=0;j<routes[i].size();j++){
                            if(source!=routes[i][j]) nextst.push_back(routes[i][j]);//去掉源车站
                        }
                        break;//查看下一个公交车
                    }
                }
            }
            return nextst;
        }
        int res=routes.size();
        vector<pair<int,int>> stationCount;//记录到达当前站点时,已经乘坐的公交车次数
        stationCount.push_back(source,0);//源站点,乘坐过0次
        function<void(int,int)> transfer=[&](int source,int count){//输入源站点与当前已经乘坐的第几辆车
            if(source==target){
                if(res>count) res=count;//当前结果与历史结果取最小值
                return;
            }
            auto nextst =getnext(source);//获取可换乘点
            bool flag=false;//标志是否经过目标站点
            for(int x:nextst){
                for(int j=0;j<stationCount.size();j++){//遍历已经换乘过的站点
                    if(x==stationCount[j].first){//如果可达到站点已经选过,则判断上次乘坐时已经乘坐的公交车次数是否比本次多
                    //只能少,不能多,防止循环套娃
                        if(stationCount[j].second>count+1){//count为到达源站点已经乘坐的第几辆车
                            stationCount[j].second = count+1;//将较小的赋值给标记数组
                            transfer(x,count+1);//到达目标站点后,乘车数+1
                        }
                        flag=true;
                        break;//已经经过站点,跳出遍历
                    }
                }
                if(!flag){//目标站点为新站
                    stationCount.push_back(x,count+1);
                    transfer(x,count+1);
                }
                flag=false;
            }
        };
        transfer(source,0);
        return res;
    }
};

答案(BFS)

最关键的是画图
将每个有相同站点的公交车进行连线长度为1,构建一个图

class Solution {
public:
    int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
        if (source == target) {
            return 0;
        }

        int n = routes.size();
        vector<vector<int>> edge(n, vector<int>(n));
        unordered_map<int, vector<int>> rec;
        for (int i = 0; i < n; i++) {
            for (int site : routes[i]) {
                for (int j : rec[site]) {
                    edge[i][j] = edge[j][i] = true;
                }
                rec[site].push_back(i);
            }
        }

        vector<int> dis(n, -1);
        queue<int> que;
        for (int bus : rec[source]) {
            dis[bus] = 1;
            que.push(bus);
        }
        while (!que.empty()) {
            int x = que.front();
            que.pop();
            for (int y = 0; y < n; y++) {
                if (edge[x][y] && dis[y] == -1) {
                    dis[y] = dis[x] + 1;
                    que.push(y);
                }
            }
        }

        int ret = INT_MAX;
        for (int bus : rec[target]) {
            if (dis[bus] != -1) {
                ret = min(ret, dis[bus]);
            }
        }
        return ret == INT_MAX ? -1 : ret;
    }
};

总结

pair基本使用
链接: pair基本使用.
3,pair对象的操作

访问两个元素操作可以通过first和sencond访问:

pair<int ,double> p1;
p1.first = 1;
p1.second = 2.5;
cout<<p1.first<<' '<<p1.second<<endl;
 
//输出结果:1 2.5
string firstBook;
if(author.first=="James" && author.second=="Joy")
    firstBook="Stephen Hero";
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值