Leetcode 每日一题和每日一题的下一题刷题笔记 28/30

276 阅读2分钟

Leetcode 每日一题和每日一题的下一题刷题笔记 28/30

写在前面

这是我参与更文挑战的第28天,活动详情查看:更文挑战

快要毕业了,才发现自己被面试里的算法题吊起来锤。没办法只能以零基础的身份和同窗们共同加入了力扣刷题大军。我的同学们都非常厉害,他们平时只是谦虚,口头上说着自己不会,而我是真的不会。。。乘掘金鼓励新人每天写博客,我也凑个热闹,记录一下每天刷的前两道题,这两道题我精做。我打算每天刷五道题,其他的题目嘛,也只能强行背套路了,就不发在博客里了。

本人真的只是一个菜鸡,解题思路什么的就不要从我这里参考了,编码习惯也需要改进,各位如果想找刷题高手请教问题我觉得去找 宫水三叶的刷题日记 这位大佬比较好。我在把题目做出来之前尽量不去看题解,以免和大佬的内容撞车。

另外我也希望有得闲的大佬提供一些更高明的解题思路给我,欢迎讨论哈!

好了废话不多说开始第二十八天的前两道题吧!

2021.6.28 每日一题

815. 公交路线

这道题是求换乘最小次数,也就是说只要一条线路的站名能覆盖上需要去的地方就可以。然后把所有可能的换乘情况全部列出来,找换乘次数最小的那个就是答案。这道题这种思路还是 BFS。其实这道题的思路有点像 A* 了,虽然我用的不熟,但是往概念上套我还是会的。首先遍历所有的路线,把包含起点站的路线归一类,包含终点站的路线归一类。然后枚举一对路线,一条来自前面的集合,一条来自后面的集合,分别称为路线 i 和路线 j(i, j) 中如果两条路线中有相同的车站,那么 edge[i][j] = edge[j][i] = 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));
        vector<int> sourceBuses;
        vector<int> targetBuses;
        unordered_map<int, unordered_set<int>> busSites;
        for (int i = 0; i < n; i++) {
            for (int& site:routes[i]) {
                busSites[i].insert(site);
                if (site == source) {
                    sourceBuses.push_back(i);
                }
                if (site == target) {
                    targetBuses.push_back(i);
                }
            }
        }
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int& site:routes[j]) {
                    if (busSites[i].count(site)) {
                        edge[i][j] = edge[j][i] = 1;
                    }
                }
            }
        }
        vector<int> dis(n, -1);
        queue<int> que;
        for (int& bus:sourceBuses) {
            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:targetBuses) {
            if (dis[bus] != -1) {
                ret = min(ret, dis[bus]);
            }
        }
        return ret == INT_MAX ? -1 : ret;
    }
};

image.png

2021.6.28 每日一题下面的题

1796. 字符串中第二大的数字

这道题看题目写话。直接上代码


class Solution {
public:
    int secondHighest(string s) {
        set<int> sett;
        for(char ch:s)
        {
            if(isdigit(ch))
                sett.insert(static_cast<int>(ch-'0'));
        }
        if(sett.size()<2) return -1;
        int a=0,b=0;
        for(int i:sett)
        {
            if(i>b) b=i;
            if(b>a) swap(a,b);
        }
        return b;
    }
};

image.png

小结

公交路线典型的 BFS,用点来构造集合,玩两点构成的边。这里立一个 flag,后面整理这篇文章的时候试一下 A* 和另外的构造集合的方法。

看题写话简单题,我也不求提速刷双百了。

参考链接