力扣第248场周赛总结

力扣第248场周赛总结

    • LeetCode 5800. 基于排列构建数组
    • LeetCode 5801. 消灭怪物的最大数量
    • LeetCode 5802. 统计好数字的数目
    • LeetCode 5803. 最长公共子路径

本次周赛主要用到了基础课里的贪心,快速幂和字符串哈希

LeetCode 5800. 基于排列构建数组

新建数组直接代就是了,签到题

class Solution {
    public int[] buildArray(int[] nums) {
        int[] ans = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            ans[i] = nums[nums[i]];
        }
        return ans;
    }
}

LeetCode 5801. 消灭怪物的最大数量

这个题,你直接拿暴力写肯定超时,写暴力逻辑也挺复杂的,
力扣这几场周赛的第二题都是贪心,做的时候可以往这上面靠一靠。
时间 = 距离 / 速度

所以排序以后我们可以发现,如果arr[i] <= i 的话,说明有怪物到达了城市,此时输出结果。否则最后输出数组长度。

class Solution {
    public int eliminateMaximum(int[] dist, int[] speed) {
        double[] arr = new double[dist.length];
        for(int i = 0; i < dist.length; i++){
            arr[i] = (double)dist[i]/speed[i];
        }
        Arrays.sort(arr);
        for(int i = 0; i < dist.length; i++){
            if(arr[i]<=i){
                return i;
            }
        }
        return dist.length;
    }
}

LeetCode 5802. 统计好数字的数目

快速幂经典例题,做的时候先去读懂样例:
我们能发现奇数位有4种,偶数位有5种,我们就是要判断有几个奇数,几个偶数,偶数为n/2,奇数为(n+1)/2;
则结果为 4的n/2次 * 5的 (n+1)/2次就是答案,因为n很大,所以必须用快速幂。

class Solution {
    int c = (int)(1e9+7);
    public int countGoodNumbers(long n) {
         return (int)(qmi(4,n/2)*qmi(5,(n+1)/2)%c);
    }
    long qmi(long a,long b){
        long res = 1;
        while(b!=0){
            if((b & 1) == 1){
                res = Math.floorMod(res*1L*a,c);
            }
            a = Math.floorMod(a*1L*a,c);
            b = b >> 1;
        }
        return res;
    }
}

LeetCode 5803. 最长公共子路径

这个题GG,贴一波yxc的代码吧!!!欢迎大家来到ACWING社区去看看y总的讲解

typedef unsigned long long ULL;
const int N = 100010;

ULL h[N], p[N];

ULL get(int l, int r)
{
    return h[r] - h[l - 1] * p[r - l + 1];
}

class Solution {
public:
    vector<vector<int>> paths;
    unordered_map<ULL, int> cnt, S;

    bool check(int mid) {
        cnt.clear(), S.clear();
        p[0] = 1;
        int k = 0;
        for (auto& str: paths) {
            int n = str.size();
            for (int i = 1; i <= n; i ++ )
            {
                p[i] = p[i - 1] * 133331;
                h[i] = h[i - 1] * 133331 + str[i - 1];
            }
            for (int i = mid; i <= n; i ++ ) {
                auto t = get(i - mid + 1, i);
                if (!S.count(t) || S[t] != k) {
                    S[t] = k;
                    cnt[t] ++ ;
                }
            }
            k ++ ;
        }
        int res = 0;
        for (auto& [k, v]: cnt) res = max(res, v);
        return res == paths.size();
    }

    int longestCommonSubpath(int n, vector<vector<int>>& _paths) {
        paths = _paths;
        n = 0;
        int l = 0, r = N;
        for (auto& p: paths) {
            n += p.size();
            r = min(r, (int)p.size());
        }

        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(mid)) l = mid;
            else r = mid - 1;
        }
        return r;
    }
};

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/1410395/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

okk,说实话,对已有知识的灵活变通才是真正的学习,学习算法真不是一朝一夕的事,要经常进行总结!!!

你可能感兴趣的:(算法,acwing,leetcode,算法,数据结构,周赛)