LeetCode第 73 场双周赛题解
6024. 数组中紧跟 key 之后出现最频繁的数字
题目描述:给你一个数组\(nums\)和一个数字\(val\),求下标中满足\(1 \leq i < n , nums_{i - 1} = val\),对于所有满足条件的\(i\),求出现次数最多的\(nums_i\)。
思路:根据题意模拟即可
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
int mostFrequent(vector& nums, int key) {
vectorcnt(1001 , 0);
for(int i = 1 ; i < nums.size() ; ++i) if(nums[i - 1] == key) cnt[nums[i]]++;
int res = -1 , ct = 0;
for(int i = 1 ; i <= 1000 ; ++i) if(cnt[i] > ct) ct = cnt[i] , res = i;
return res;
}
};
5217. 将杂乱无章的数字排序
题目描述:将给定数组按照给定排序规则进行稳定的排序。
思路:可以使用map
嵌套vector
实现稳定排序,也可以记录下标直接使用sort
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
vector sortJumbled(vector& mapping, vector& nums) {
map>mp;
auto f = [&](int x){
int a = 0;
string s = to_string(x);
for(auto& c : s) a = a * 10 + mapping[c - '0'];
return a;
};
for(auto& num : nums) mp[f(num)].push_back(num);
vectorres;
for(auto& iter : mp)
for(auto& v : iter.second) res.push_back(v);
return res;
}
};
5300. 有向无环图中一个节点的所有祖先
题目描述:给你一个有向无环图,对于每一个顶点,求所有能到达它的顶点的集合。
思路:比较裸的拓扑排序,然后过程中用set
维护一下父结点集合即可。
时间复杂度:\(O(n^2logn)\)
参考代码:
class Solution {
public:
vector> getAncestors(int n, vector>& edges) {
vector>graph(n);
vectorincome(n, 0);
for (auto& edge : edges) {
int u = edge[0], v = edge[1];
graph[u].push_back(v);
income[v]++;
}
for (int i = 0; i < n; ++i) sort(begin(graph[i]), end(graph[i]));
vector>a(n);
queueq;
for (int i = 0; i < n; ++i) {
if (income[i] != 0) continue;
q.push(i);
}
while (!q.empty()) {
int u = q.front();
q.pop();
for (auto& v : graph[u]) {
a[v].insert(u);
for (auto& t : a[u]) a[v].insert(t);
if (--income[v] == 0) q.push(v);
}
}
vector>res(n);
for (int i = 0; i < n; ++i) {
for (auto& t : a[i]) res[i].push_back(t);
}
return res;
}
};
5237. 得到回文串的最少操作次数
题目描述:给定一个字符串,每次操作可以交换相邻两个字符,问最少经过多少次操作可以使得字符串变回文,保证题目有解。
思路:比较明显的贪心,可以记录一下每个字符出现的位置,然后遍历枚举,对于当前的枚举的字符,取离他最远的相同字符移动到对称位置会最优。注意特判奇回文的情况。可以使用树状数组维护。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
private:
vectortr;
vector>g;
vectorused;
string str;
int n;
int lowbit(int x){ return x & -x;}
int sum(int idx){
int ans=0;
while(idx){
ans+=tr[idx];
idx-=lowbit(idx);
}
return ans;
}
void add(int idx ,int val){
while(idx <= n){
tr[idx] += val;
idx += lowbit(idx);
}
return ;
}
int solve(){
for(int i=1; i<=n+1; i++) add(i,1);
int res = 0;
for(int i=1; i<=n; i++){
if(!used[i]){
int idx = str[i] - 'a';
int u = g[idx].back();
if(i == u) res += (sum(n) - sum(i))/2;
else res += sum(n) - sum(u);
add(u, -1);
add(i, -1);
used[i] = used[u] = 1;
g[idx].pop_back();
}
}
return res;
}
public:
int minMovesToMakePalindrome(string s) {
n = s.size();
s = ' ' + s;
str = s;
tr = vector(n + 1 , 0);
used = vector(n + 1 , false);
g = vector>(26);
for(int i=1; i<=n; i++) g[s[i] - 'a'].push_back(i);
return solve();
}
};