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;
}
};