leetcode每日一题day7(24.9.17)——公交线路


思路:看到题就隐隐约约觉得是搜索,依据当前信息只知道一条线路经过哪些站点,而在某个站点时可以换乘哪些线路缺是不知道的,所有这也是必须有的信息,即在i条线路到达A站后,通过A站可换乘线路,在此线路上到达B站,至此完成回路即 在i->Aj->B,这些换乘和线路信息的至此完成闭合即可开始搜索。

        搜索思路

                对于采用广度优先:即使用队列进行操作,如果当前站点不是目标站点,则对于当前所在站点,扩展出所有代价为1的可到达的站点,即遍历当前能换乘的线路,这些线路上的所有站点都是代价为1的站点,对这些进行入队,(如果对广度不熟悉建议找个广度搜索的模板看看,主要注意队列元素所在层数即,由第一层扩展出来的节点,层次将会增加,下方代码表现在while内的第一个for循环,用意就在于对队列元素分层处理,不是一股脑的往后,而是遍历完当前层所有队列元素后,对层数标记进行增加,再重复对下一层次进行相同操作),最后需要注意的是如果某个站点或线路已经访问过,就不再继续访问,因为访问了再对其进行访问,这无疑使莫名增加了层次,这对于要求最少是不好的。

                对于采用深度优先:采用分支限界,加回溯应该是可以实现的,即某一时刻找到了目标站点,则对其进行层次的记录,如果后续搜索,到达当前层次还没找到则不必再找,没有写代码(后续有机会再补,)

代码

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

        int nn = 0;
        for (auto& e : routes)
            for (auto& ee : e)
                nn = max(nn, ee);

        if (max(source, target) > nn)
            return -1;
        vector<vector<int>> station_bus(nn+1);
        for (int i = 0; i < routes.size(); i++) {
            for (int j = 0; j < routes[i].size(); j++) {
                station_bus[routes[i][j]].push_back(i);
            }
        }
        vector<int> station_is(nn+1, 0);
        vector<int> bus_is(routes.size(), 0);
        queue<int> me;
        me.push(source);
        station_is[source] = 1;
        int ans = 0;
        while (!me.empty()) {
            int n = me.size();
            for (int i = 0; i < n; i++) {
                if (me.front() == target) {
                    // cout<<me.front()<<endl;
                    return ans;
                }
                for (int c : station_bus[me.front()]) {
                    if (bus_is[c])
                        continue;
                    for (int k = 0; k < routes[c].size(); k++) {
                        if (station_is[routes[c][k]]) {
                            continue;
                        }
                        me.push(routes[c][k]);
                        station_is[routes[c][k]] = 1;
                    }
                    bus_is[c] = 1;
                }
                me.pop();
            }
            ans++;
        }
        return -1;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值