• LeetCode(Weekly Contest 182)题解


    0. 前言

    1. 题解

    1.1 5368. 找出数组中的幸运数(1394. Find Lucky Integer in an Array)

    class Solution {
    public:
        int findLucky(vector<int>& arr) {
            int len = arr.size();
            map<int, int> cnt;
            for (auto v : arr) {
                cnt[v]++;
            }
            int ans = -1;
            for (auto it = cnt.begin() ; it != cnt.end() ; it++) {
                if (it->first == it->second) {
                    ans = it->first;
                }
            }
            return ans;
        }
    };

    1.2 5369. 统计作战单位数(1395. Count Number of Teams)

    class Solution {
    public:
        int numTeams(vector<int>& rating) {
            int n = rating.size();
            int ans = 0;
            if (n < 3)  return 0;
            for (int i = 1 ; i < n-1 ; i++) {
                int ll = 0, ls = 0, rl = 0, rs = 0;
                for (int j = 0 ; j < i ; j++) {
                    if (rating[j] < rating[i]) {
                        ls++;
                    } else if (rating[j] > rating[i]) {
                        ll++;
                    } 
                }
                for (int j = i+1 ; j < n ; j++) {
                    if (rating[j] < rating[i]) {
                        rs++;
                    } else if (rating[j] > rating[i]) {
                        rl++;
                    } 
                }
                ans += ls * rl + ll * rs;
            }
            return ans;
        }
    };

    1.3 5370. 设计地铁系统(1396. Design Underground System)

    class UndergroundSystem {
    public:
        unordered_map<int, pair<string, int>> passenger;
        unordered_map<string, unordered_map<string, pair<int, int>>> startEnd;
        UndergroundSystem() {
            
        }
        
        void checkIn(int id, string stationName, int t) {
            passenger[id] = make_pair(stationName, t);
        }
        
        void checkOut(int id, string stationName, int t) {
            string start = passenger[id].first;
            if (startEnd[start].find(stationName) == startEnd[start].end()) {
                startEnd[start][stationName] = make_pair(t-passenger[id].second, 1);
            } else {
                startEnd[start][stationName].first += t-passenger[id].second;
                startEnd[start][stationName].second += 1;
            }
        }
        
        double getAverageTime(string startStation, string endStation) {
            return (double)startEnd[startStation][endStation].first / (double)startEnd[startStation][endStation].second;
        }
    };
    
    /**
     * Your UndergroundSystem object will be instantiated and called as such:
     * UndergroundSystem* obj = new UndergroundSystem();
     * obj->checkIn(id,stationName,t);
     * obj->checkOut(id,stationName,t);
     * double param_3 = obj->getAverageTime(startStation,endStation);
     */

    1.4 5371. 找到所有好字符串(1397. Find All Good Strings)

    • 中文版题目描述:https://leetcode-cn.com/classic/problems/find-all-good-strings/description/
    • 英文版题目描述:https://leetcode.com/problems/find-all-good-strings/description/
    • 思路:数位 DP + KMP:
      • 数位 DP 问题往往都是这样的题型,给定一个闭区间 [l, r],让你求这个区间中满足某种条件的数的总数
      • 首先我们将问题转化成更加简单的形式,设 f[i] 表示在区间 [1,i] 中满足条件的数的数量,那么所求的答案就是 f[r] - f[l-1]
      • 数位 dp 中,dp 数组永远为 dp[i][state][eq]
      • 其中,i 表示前 i 位,即为结果字符串的前缀
      • state 描述前缀的状态
      • eq 表示前缀是否与 s[0,i) 相等
      • dp[i][state][eq] 就是有多少个长度为 i 的前缀,其状态为 state 且相等状态等于 eq
      • 在本题中,state 表示前缀与 evil 字符串匹配的最长长度
      • 初始化 dp[0][*][1],当长度为 0、匹配长度为0 时,只有 dp[0][0][1] = 1,其它位置都为 0
      • 当前匹配 state 长度后,增加一个字符 cur,与 evil 字符串匹配的最大长度怎么计算,根据 kmp 的 next 数组计算即可
      • 每次通过 dp[i] 扩展 dp[i+1] 的状态,具体情况可以分为,通过 dp[i][state][0](前缀长期为 i 且小于 s[i:])、dp[i][state][1](前缀长期为 i 且等于 s[i:])扩展出 dp[i+1][ns][0] 和 dp[i+1][ns][1] 等状态
      • 其中 ns 为 state 通过 next 数组在添加一个字符 cur 后的最大前缀匹配长度
    • 代码如下:
    class Solution {
    public:
        vector<int> getNextArray(string pattern) {
            int len = pattern.length();
            vector<int> res(len+1,0);
            int j = 0;
            for (int i = 1 ; i < len ; i++) {
                while (j && pattern[i] != pattern[j])   j = res[j];
                if (pattern[i] == pattern[j])   j++;
                res[i+1] = j;
            }
            return res;
        }
        int getNextState(int state, vector<int>& next, string pattern, char cur) {
            int j = state;
            while (j > 0 && pattern[j] != cur)    j = next[j];
            if (pattern[j] == cur)    j++;
            return j;
        }
        bool dec(int n, string& s) {
            bool result = false;
            for (int i = n-1 ; i >= 0 ; i--) {
                if (s[i] > 'a') {
                    s[i]--;
                    result = true;
                    break;
                } else {
                    s[i] = 'z';
                }
            }
            return result;
        }
        long long dfs(int n, string s, vector<int>& next, string pattern) {
            long long mod = (long long)1000000007;
            int lp = pattern.length();
            vector<vector<vector<long long>>> dp = vector<vector<vector<long long>>>(n+1, vector<vector<long long>>(lp+1, vector<long long>(2, 0)));
            dp[0][0][1] = 1;
            for (int i = 0 ; i < n ; i++) {
                for (int j = 0 ; j < lp ; j++) {
                    int ns = getNextState(j, next, pattern, s[i]);
                     dp[i+1][ns][1] = (dp[i+1][ns][1] + dp[i][j][1]) % mod;
                    for (char k = 'a' ; k <= 'z' ; k++) {
                        ns = getNextState(j, next, pattern, k);
                        dp[i+1][ns][0] = (dp[i+1][ns][0] + dp[i][j][0]) % mod;
                    }
                    for (char k = 'a' ; k < s[i] ; k++) {
                        ns = getNextState(j, next, pattern, k);
                        dp[i+1][ns][0] = (dp[i+1][ns][0] + dp[i][j][1]) % mod;
                    }
                }
            }
            long long result = (long long)0;
            for (int i = 0 ; i < lp ; i++) {
                result = (result + dp[n][i][0]) % mod;
                result = (result + dp[n][i][1]) % mod;
            }
            return result;
        }
        int findGoodStrings(int n, string s1, string s2, string evil) {
            vector<int> next = getNextArray(evil);
            bool flag = dec(n, s1);
            long long ans = (long long)0;
            if (flag) {
                ans = dfs(n, s2, next, evil) - dfs(n, s1, next, evil);
            } else {
                ans = dfs(n, s2, next, evil);
            }
            if (ans < 0) {
                ans += (long long)1000000007;
            }
            return (int)ans;
        }
    };

    2. 参考文献

  • 相关阅读:
    在xp中用sc命令安装自己写的服务的具体步骤
    .net中导出excel数据不全的解决方案
    转载:20092010年中国商业智能市场分析
    xp发布多维数据集过程
    .net中导出excel时不能自动显示网格线的解决方案
    .net中访问多维数据集报错
    在xp中用DOS添加服务时,输入SC命令提示不可用的解决方案
    jenkins在奴隶机上安装dotnetsdk
    .NET Core 使用jenkins发布代码
    jenkins添加linux方法
  • 原文地址:https://www.cnblogs.com/wangao1236/p/12595914.html
Copyright © 2020-2023  润新知