zoukankan      html  css  js  c++  java
  • [LeetCode] 815. Bus Routes 公交路线

    We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->... forever.

    We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what is the least number of buses we must take to reach our destination? Return -1 if it is not possible.

    Example:
    Input: 
    routes = [[1, 2, 7], [3, 6, 7]]
    S = 1
    T = 6
    Output: 2
    Explanation: 
    The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
    

    Note:

    • 1 <= routes.length <= 500.
    • 1 <= routes[i].length <= 500.
    • 0 <= routes[i][j] < 10 ^ 6.

    有一个表示公交路线的二维数组,每一行routes[i]代表一辆公交车循环运行的环形路线,求最少需要坐多少辆公交车才能从巴士站S到达T。

    解法:BFS,先对原来的二维数组进行处理,二维数组的每一行代表这辆公交车能到达的站点,用HashMap记录某站点有哪个公交经过。这样处理完以后就知道每一个站点都有哪个公交车经过了。然后用一个queue记录当前站点,对于当前站点的所有经过的公交循环,每个公交又有自己的下一个站点。可以想象成一个图,每一个公交站点 被多少个公交经过,也就是意味着是个中转站,可以连通到另外一个公交上, 因为题目求的是经过公交的数量而不关心经过公交站点的数量,所以在BFS的时候以公交(也就是routes的下标)来扩展。

    Java:

    class Solution {
        public int numBusesToDestination(int[][] routes, int S, int T) {
           HashSet<Integer> visited = new HashSet<>();
           Queue<Integer> q = new LinkedList<>();
           HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();
           int ret = 0; 
            
           if (S==T) return 0; 
            
           for(int i = 0; i < routes.length; i++){
                for(int j = 0; j < routes[i].length; j++){
                    ArrayList<Integer> buses = map.getOrDefault(routes[i][j], new ArrayList<>());
                    buses.add(i);
                    map.put(routes[i][j], buses);                
                }       
            }
                    
           q.offer(S); 
           while (!q.isEmpty()) {
               int len = q.size();
               ret++;
               for (int i = 0; i < len; i++) {
                   int cur = q.poll();
                   ArrayList<Integer> buses = map.get(cur);
                   for (int bus: buses) {
                        if (visited.contains(bus)) continue;
                        visited.add(bus);
                        for (int j = 0; j < routes[bus].length; j++) {
                            if (routes[bus][j] == T) return ret;
                            q.offer(routes[bus][j]);  
                       }
                   }
               }
            }
            return -1;
        }
    }  

    Java:

    public int numBusesToDestination(int[][] routes, int S, int T) {
            HashMap<Integer, HashSet<Integer>> to_routes = new HashMap<>();
            for (int i = 0; i < routes.length; ++i)
                for (int j : routes[i]) {
                    if (!to_routes.containsKey(j)) to_routes.put(j, new HashSet<Integer>());
                    to_routes.get(j).add(i);
                }
            Queue<Point> bfs = new ArrayDeque();
            bfs.offer(new Point(S, 0));
            HashSet<Integer> seen = new HashSet<>();
            seen.add(S);
            while (!bfs.isEmpty()) {
                int stop = bfs.peek().x, bus = bfs.peek().y;
                bfs.poll();
                if (stop == T) return bus;
                for (int route_i : to_routes.get(stop))
                    for (int next_stop : routes[route_i])
                        if (!seen.contains(next_stop)) {
                            seen.add(next_stop);
                            bfs.offer(new Point(next_stop, bus + 1));
                        }
            }
            return -1;
        }
    

    Python:

    def numBusesToDestination(self, routes, S, T):
            to_routes = collections.defaultdict(set)
            for i,route in enumerate(routes):
                for j in route: to_routes[j].add(i)
            bfs = [(S,0)]
            seen = set([S])
            for stop, bus in bfs:
                if stop == T: return bus
                for route_i in to_routes[stop]:
                    for next_stop in routes[route_i]:
                        if next_stop not in seen:
                            bfs.append((next_stop, bus+1))
                            seen.add(next_stop)
                    routes[route_i] = []
            return -1
    

    Python:

    # Time:  O(|V| + |E|)
    # Space: O(|V| + |E|)
    
    import collections
    
    
    class Solution(object):
        def numBusesToDestination(self, routes, S, T):
            """
            :type routes: List[List[int]]
            :type S: int
            :type T: int
            :rtype: int
            """
            if S == T:
                return 0
    
            to_route = collections.defaultdict(set)
            for i, route in enumerate(routes):
                for stop in route:
                    to_route[stop].add(i)
    
            result = 1
            q = [S]
            lookup = set([S])
            while q:
                next_q = []
                for stop in q:
                    for i in to_route[stop]:
                        for next_stop in routes[i]:
                            if next_stop in lookup:
                                continue
                            if next_stop == T:
                                return result
                            next_q.append(next_stop)
                            to_route[next_stop].remove(i)
                            lookup.add(next_stop)
                q = next_q
                result += 1
    
            return -1  

    C++:

    int numBusesToDestination(vector<vector<int>>& routes, int S, int T) {
            unordered_map<int, unordered_set<int>> to_route;
            for (int i = 0; i < routes.size(); ++i) for (auto& j : routes[i]) to_route[j].insert(i);
            queue<pair<int, int>> bfs; bfs.push(make_pair(S, 0));
            unordered_set<int> seen = {S};
            while (!bfs.empty()) {
                int stop = bfs.front().first, bus = bfs.front().second;
                bfs.pop();
                if (stop == T) return bus;
                for (auto& route_i : to_route[stop]) {
                    for (auto& next_stop : routes[route_i])
                        if (seen.find(next_stop) == seen.end()) {
                            seen.insert(next_stop);
                            bfs.push(make_pair(next_stop, bus + 1));
                        }
                    routes[route_i].clear();
                }
            }
            return -1;
        }
    

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    变量可变性问题
    Android 创建Listener监听器形式选择:匿名内部类?外部类?
    linux下安装zookeeper
    翻页工具类
    将哈夫曼树转化成二叉树
    Activity的启动流程分析
    题目1186:打印日期
    数据库设计--数据流图(DFD)
    c#基础之数组
    10.3.1 一个CONNECT BY的样例
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9802088.html
Copyright © 2011-2022 走看看