天天看点

leetcode周赛248

1.瞎搞

给你一个 从 0 开始的排列 nums(下标也从 0 开始)。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i(0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans 。

从 0 开始的排列 nums 是一个由 0 到 nums.length - 1(0 和 nums.length - 1 也包含在内)的不同整数组成的数组。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/build-array-from-permutation

class Solution {
public:
    vector<int> buildArray(vector<int>& nums) {
        vector<int> ans;
        for(int i = 0; i < nums.size(); i++){
            ans.push_back(nums[nums[i]]);
        }
        return ans;
    }
};
           

2.排序加贪心

你正在玩一款电子游戏,在游戏中你需要保护城市免受怪物侵袭。给你一个 下标从 0 开始 且长度为 n 的整数数组 dist ,其中 dist[i] 是第 i 个怪物与城市的 初始距离(单位:米)。

怪物以 恒定 的速度走向城市。给你一个长度为 n 的整数数组 speed 表示每个怪物的速度,其中 speed[i] 是第 i 个怪物的速度(单位:米/分)。

怪物从 第 0 分钟 时开始移动。你有一把武器,并可以 选择 在每一分钟的开始时使用,包括第 0 分钟。但是你无法在一分钟的中间使用武器。这种武器威力惊人,一次可以消灭任一还活着的怪物。

一旦任一怪物到达城市,你就输掉了这场游戏。如果某个怪物 恰 在某一分钟开始时到达城市,这会被视为 输掉 游戏,在你可以使用武器之前,游戏就会结束。

返回在你输掉游戏前可以消灭的怪物的 最大 数量。如果你可以在所有怪物到达城市前将它们全部消灭,返回  n 。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/eliminate-maximum-number-of-monsters

class Solution {
public:
    int eliminateMaximum(vector<int>& dist, vector<int>& speed) {
        int num = 0;
        for(int i = 0; i < dist.size(); i++)  dist[i] = (dist[i] - 1) / speed[i];
        sort(dist.begin(), dist.end());
        for(int i = 0; i < dist.size(); i++){
            if(dist[i] < i) return i;
        }
        
        return dist.size();
    }

};
           

3.快速幂

我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (2,3,5 或 7)。

比方说,"2582" 是好数字,因为偶数下标处的数字(2 和 8)是偶数且奇数下标处的数字(5 和 2)为质数。但 "3245" 不是 好数字,因为 3 在偶数下标处但不是偶数。

给你一个整数 n ,请你返回长度为 n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对 109 + 7 取余后返回 。

一个 数字字符串 是每一位都由 0 到 9 组成的字符串,且可能包含前导 0 。

示例 1:

输入:n = 1

输出:5

解释:长度为 1 的好数字包括 "0","2","4","6","8" 。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/count-good-numbers

const int mod = 1e9 + 7;

long long mod_pow(long long x,long long n)
{
	long long res = 1;
	while(n > 0)
	{
		if(n & 1) res = res * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return res % mod;
}

class Solution {
public:
    int countGoodNumbers(long long n) {
        long long num1 = n / 2;
        if(n % 2 == 1) num1 += 1;
        num1 = ((mod_pow(5L, num1) * mod_pow(4L, n / 2)) % mod);
        return num1;
    }
};
           

4. 最长公共子路径 hash+二分看出现的次数是否为n次

typedef unsigned long long ULL;
const int N = 100010;
ULL h[N], p[N];
vector<vector<int>> paths;
unordered_map<ULL, int> cnt, S;
ULL get(int l, int r)
{
    return h[r] - h[l - 1] * p[r - l + 1];
}
bool check(int mid, vector<vector<int>>& paths) {
    cnt.clear(), S.clear();
    for(int i = 0; i < paths.size(); i++){
        auto str = paths[i];
        int n = str.size();
        for(int j = 1; j <= n; j++)
        {
            p[j] = p[j - 1] * 133331;
            h[j] = h[j - 1] * 133331 + str[j - 1];
        }
        for(int j = mid; j <= n; j++){
            auto t = get(j - mid + 1, j);
            if (!S.count(t) || S[t] != i) {
                S[t] = i;
                cnt[t]++ ;
            }
        }
    }
    int res = 0;
    for (auto& [k, v]: cnt) res = max(res, v);
    return res == paths.size();
}
class Solution {
public:
    int longestCommonSubpath(int n, vector<vector<int>>& paths) {
        int l = 0, r = N;
        for(auto p : paths) r = min(r, int(p.size()));
        p[0] = 1;
        while(l <= r){
            int mid = l + r >> 1;
            if(check(mid, paths)) l = mid + 1; // 检测长度对mid的有没有出现过 n次
            else r = mid - 1;
        }
        return r;
    }
};