LeetCode 第422场个人周赛

目录

[Q1. 检查平衡字符串](#Q1. 检查平衡字符串)

原题链接

思路分析

AC代码

[Q2. 到达最后一个房间的最少时间 I](#Q2. 到达最后一个房间的最少时间 I)

原题链接

思路分析

AC代码

[Q3. 到达最后一个房间的最少时间 II](#Q3. 到达最后一个房间的最少时间 II)

原题链接

思路分析

AC代码

[Q4. 统计平衡排列的数目](#Q4. 统计平衡排列的数目)

原题链接

思路分析

AC代码


Q1. 检查平衡字符串

原题链接

Q1. 检查平衡字符串

思路分析

签到题,不说了

时间复杂度:O(N)

AC代码

python 复制代码
class Solution:
    def isBalanced(self, num: str) -> bool:
        num = list(map(ord, num))
        for i in range(len(num)):
            num[i] -= ord('0')
        return sum(num[0::2]) == sum(num[1::2])

Q2. 到达最后一个房间的最少时间 I

原题链接

Q2. 到达最后一个房间的最少时间 I

思路分析

无脑 dij 即可

时间复杂度:O(NM log NM)

AC代码

cpp 复制代码
using i64 = long long;
constexpr i64 inf64 = 1E18 + 7;
int dir[] = {-1, 0, 1, 0, -1};
class Solution {
public:
    int minTimeToReach(vector<vector<int>>& moveTime) {
        int n = moveTime.size(), m = moveTime[0].size();
        std::priority_queue<std::tuple<i64, int, int, int>, std::vector<std::tuple<i64, int, int, int>>, std::greater<std::tuple<i64, int, int, int>>> pq;
        std::vector<std::vector<i64>> dis(n, std::vector<i64>(m, inf64));
        pq.emplace(0, 0, 0, 1);
        dis[0][0] = 0;
        while (pq.size()) {
            auto [d, i, j, w] = pq.top();
            pq.pop();
            
            if (d > dis[i][j]) {
                continue;
            }
            
            for (int k = 0; k < 4; ++ k) {
                auto [ni, nj] = std::pair(i + dir[k], j + dir[k + 1]);
                if (ni < 0 || ni >= n || nj < 0 || nj >= m) {
                    continue;
                }
                i64 nd = std::max<i64>(d, moveTime[ni][nj]) + w;
                i64 nw = 1;
                if (dis[ni][nj] > nd) {
                    dis[ni][nj] = nd;
                    pq.emplace(nd, ni, nj, nw);
                } 
            }
        }
        return dis[n - 1][m - 1];
    }
};

Q3. 到达最后一个房间的最少时间 II

原题链接

Q3. 到达最后一个房间的最少时间 II

思路分析

无脑dij即可

时间复杂度:O(NM log NM)

AC代码

cpp 复制代码
using i64 = long long;
constexpr i64 inf64 = 1E18 + 7;
int dir[] = {-1, 0, 1, 0, -1};
class Solution {
public:
    int minTimeToReach(vector<vector<int>>& moveTime) {
        int n = moveTime.size(), m = moveTime[0].size();
        std::priority_queue<std::tuple<i64, int, int, int>, std::vector<std::tuple<i64, int, int, int>>, std::greater<std::tuple<i64, int, int, int>>> pq;
        std::vector<std::vector<i64>> dis(n, std::vector<i64>(m, inf64));
        pq.emplace(0, 0, 0, 1);
        dis[0][0] = 0;
        while (pq.size()) {
            auto [d, i, j, w] = pq.top();
            pq.pop();
            
            if (d > dis[i][j]) {
                continue;
            }
            
            for (int k = 0; k < 4; ++ k) {
                auto [ni, nj] = std::pair(i + dir[k], j + dir[k + 1]);
                if (ni < 0 || ni >= n || nj < 0 || nj >= m) {
                    continue;
                }
                i64 nd = std::max<i64>(d, moveTime[ni][nj]) + w;
                i64 nw = (w + 1) % 3;
                if (nw == 0) {
                    nw = 1;
                }
                if (dis[ni][nj] > nd) {
                    dis[ni][nj] = nd;
                    pq.emplace(nd, ni, nj, nw);
                } 
            }
        }
        return dis[n - 1][m - 1];
    }
};

Q4. 统计平衡排列的数目

原题链接

Q4. 统计平衡排列的数目

思路分析

记忆化搜索 + 组合数学

考虑 dfs(i, j, k) 为 奇位置的 序列,考虑到填 数字 i,和为 j,长度为 k时的 方案数

如果我们填了 c 个 i,那么 有 cnt[i] - c 个 i 填到 偶数位置

由于要求排列数,而奇偶位置的排列显然都是多重集排列

多重集排列数 = n! / p1! p2!...pk!

由于本题是取模,所以分母可以在递归的时候乘其逆元

即 dfs(i, j, k) = Σ dfs(i + 1, j + c * i, k + c) * inv(fac(c)) * inv(fac(cnt[i] - c))

时间复杂度:O(U^2 N^3),U = 10

AC代码

python 复制代码
P = 1_000_000_007
N = 80
fac = [1] * (N + 1)
inv = [1] * (N + 1)

for i in range(2, N + 1):
    fac[i] = fac[i - 1] * i % P
inv[N] = pow(fac[N], P - 2, P)
for i in range(N - 1, 1, -1):
    inv[i] = (i + 1) * inv[i + 1]


class Solution:
    def countBalancedPermutations(self, num: str) -> int:
        num = list(map(ord, num))
        s = 0
        for i in range(len(num)):
            num[i] -= ord('0')
            s += num[i]

        cnt = Counter(num)

        if s & 1: return 0

        @cache
        def dfs(i: int, j: int, k: int) -> int:
            if j * 2 > s: return 0
            if i == 10:
                return fac[len(num) // 2] * fac[(len(num) + 1) // 2] % P if j * 2 == s and k == len(num) // 2 else 0

            res = 0

            for c in range(cnt[i] + 1):
                res += dfs(i + 1, j + c * i, k + c) * inv[c] * inv[cnt[i] - c] % P
                res %= P

            return res

        dfs.cache_clear()

        return dfs(0, 0, 0)
相关推荐
白榆maple几秒前
(蓝桥杯C/C++)——基础算法(上)
c语言·c++·算法·蓝桥杯
程序员雷叔5 分钟前
外包功能测试就干了4周,技术退步太明显了。。。。。
功能测试·测试工具·面试·职场和发展·单元测试·测试用例·postman
道亦无名9 分钟前
WAPI加密算法
算法
q5673152314 分钟前
Python 中的字符串匹配算法
android·java·javascript·python·算法
C++忠实粉丝44 分钟前
Linux系统基础-多线程超详细讲解(5)_单例模式与线程池
linux·运维·服务器·c++·算法·单例模式·职场和发展
2401_877158731 小时前
什么是垃圾回收(Garbage Collection)?
java·开发语言·算法
阿亨仔1 小时前
Pytorch猴痘病识别
人工智能·pytorch·python·深度学习·算法·机器学习
混迹网络的权某1 小时前
蓝桥杯真题——三角回文数(C语言)
c语言·开发语言·算法·蓝桥杯·改行学it
混迹网络的权某2 小时前
蓝桥杯真题——乐乐的序列和(C语言)
c语言·算法·蓝桥杯
wheeldown2 小时前
【数据结构】快速排序
c语言·数据结构·算法·排序算法