1. 找到频率最高的元音和辅音
给你一个由小写英文字母(
'a'
到'z'
)组成的字符串s
。你的任务是找出出现频率 最高 的元音('a'
、'e'
、'i'
、'o'
、'u'
中的一个)和出现频率最高的辅音(除元音以外的所有字母),并返回这两个频率之和。注意:如果有多个元音或辅音具有相同的最高频率,可以任选其中一个。如果字符串中没有元音或没有辅音,则其频率视为 0。
一个字母x
的 频率 是它在字符串中出现的次数。
示例 1:
输入: s = "successes"
输出: 6
解释:
- 元音有:
'u'
出现 1 次,'e'
出现 2 次。最大元音频率 = 2。- 辅音有:
's'
出现 4 次,'c'
出现 2 次。最大辅音频率 = 4。- 输出为
2 + 4 = 6
。示例 2:
输入: s = "aeiaeia"
输出: 3
解释:
- 元音有:
'a'
出现 3 次,'e'
出现 2 次,'i'
出现 2 次。最大元音频率 = 3。s
中没有辅音。因此,最大辅音频率 = 0。- 输出为
3 + 0 = 3
。提示:
1 <= s.length <= 100
s
只包含小写英文字母
解题思路:维护两个(元音/辅音)最大值
class Solution {
public:
bool judge(char x){
string s="aeiou";
for(int i=0;i<s.size();i++){
if(s[i]==x){
return true;
}
}
return false;
}
int maxFreqSum(string s) {
unordered_map<char,int> mp;
for(auto& x:s){
mp[x]++;
}
int max_cnt_vo=0,max_cnt_co=0;
for(auto& [x,y]:mp){
if(judge(x)) max_cnt_vo=max(max_cnt_vo,y);
else max_cnt_co=max(max_cnt_co,y);
}
return max_cnt_vo+max_cnt_co;
}
};
2. 将所有元素变为 0 的最少操作次数
给你一个大小为
n
的 非负 整数数组nums
。你的任务是对该数组执行若干次(可能为 0 次)操作,使得 所有 元素都变为 0。在一次操作中,你可以选择一个子数组
[i, j]
(其中0 <= i <= j < n
),将该子数组中所有 最小的非负整数 的设为 0。返回使整个数组变为 0 所需的最少操作次数。
一个 子数组 是数组中的一段连续元素。
示例 1:
输入: nums = [0,2]
输出: 1
解释:
- 选择子数组
[1,1]
(即[2]
),其中最小的非负整数是 2。将所有 2 设为 0,结果为[0,0]
。- 因此,所需的最少操作次数为 1。
示例 2:
输入: nums = [3,1,2,1]
输出: 3
解释:
- 选择子数组
[1,3]
(即[1,2,1]
),最小非负整数是 1。将所有 1 设为 0,结果为[3,0,2,0]
。- 选择子数组
[2,2]
(即[2]
),将 2 设为 0,结果为[3,0,0,0]
。- 选择子数组
[0,0]
(即[3]
),将 3 设为 0,结果为[0,0,0,0]
。- 因此,最少操作次数为 3。
示例 3:
输入: nums = [1,2,1,2,1,2]
输出: 4
解释:
- 选择子数组
[0,5]
(即[1,2,1,2,1,2]
),最小非负整数是 1。将所有 1 设为 0,结果为[0,2,0,2,0,2]
。- 选择子数组
[1,1]
(即[2]
),将 2 设为 0,结果为[0,0,0,2,0,2]
。- 选择子数组
[3,3]
(即[2]
),将 2 设为 0,结果为[0,0,0,0,0,2]
。- 选择子数组
[5,5]
(即[2]
),将 2 设为 0,结果为[0,0,0,0,0,0]
。- 因此,最少操作次数为 4。
提示:
1 <= n == nums.length <= 10^5
0 <= nums[i] <= 10^5
解题思路:用个栈/vector数组进行维护,
请结合图和代码进行理解
class Solution {
public:
int minOperations(vector<int>& nums) {
int ans=0;
stack<int> st;
for(int& x: nums){
while(!st.empty()&&st.top()>x){
st.pop();
}
if(!st.empty()&&x==st.top()){
continue;
}
if (x!=0){
ans++;
st.push(x);
}
}
return ans;
}
};
3. K 条边路径的最大边权和
给你一个整数
n
和一个包含n
个节点(编号从 0 到n - 1
)的 有向无环图(DAG)。该图由二维数组edges
表示,其中edges[i] = [ui, vi, wi]
表示一条从节点ui
到vi
的有向边,边的权值为wi
同时给你两个整数
k
和t
。你的任务是确定在图中边权和 尽可能大的 路径,该路径需满足以下两个条件:
- 路径包含 恰好
k
条边;- 路径上的边权值之和 严格小于
t
。返回满足条件的一个路径的 最大 边权和。如果不存在这样的路径,则返回
-1
。
解题思路:记忆化搜索
class Solution {
public:
int maxWeight(int n, vector<vector<int>>& edges, int k, int t) {
vector<vector<pair<int, int>>> graph(n);
for (auto& edge : edges) {
int x = edge[0], y = edge[1], z = edge[2];
graph[x].emplace_back(y, z);
}
vector<vector<unordered_map<int, int>>> memo(n, vector<unordered_map<int, int>>(k+1));
int ans = -1;
auto dfs = [&](this auto&&dfs,int x, int s, int sum) {
if (s == k) {
if (sum < t) ans = max(ans, sum);
return;
}
if (memo[x][s].count(sum)) {
return;
}
memo[x][s][sum] = 1;
for (auto& [y, wt] : graph[x]) {
if (sum + wt < t) {
dfs(y, s + 1, sum + wt);
}
}
};
for (int i = 0; i < n; ++i) {
dfs(i, 0, 0);
}
return ans;
}
};
4. 子树反转和
给你一棵以节点
0
为根节点包含n
个节点的无向树,节点编号从 0 到n - 1
。该树由长度为n - 1
的二维整数数组edges
表示,其中edges[i] = [ui, vi]
表示节点ui
和vi
之间有一条边。同时给你一个整数
k
和长度为n
的整数数组nums
,其中nums[i]
表示节点i
的值。你可以对部分节点执行 反转操作 ,该操作需满足以下条件:
子树反转操作:
当你反转一个节点时,以该节点为根的子树中所有节点的值都乘以 -1。
反转之间的距离限制:
你只能在一个节点与其他已反转节点“足够远”的情况下反转它。
具体而言,如果你反转两个节点
a
和b
,并且其中一个是另一个的祖先(即LCA(a, b) = a
或LCA(a, b) = b
),那么它们之间的距离(它们之间路径上的边数)必须至少为k
。返回应用 反转操作 后树上节点值的 最大可能 总和 。
在一棵有根树中,某个节点
v
的子树是指所有路径到根节点包含v
的节点集合。
解题思路:记忆化搜索
class Solution {
public:
long long subtreeInversionSum(vector<vector<int>>& edges, vector<int>& nums, int k) {
int n = nums.size();
vector<vector<int>> graph(n);
for (auto& e : edges) {
int x = e[0], y = e[1];
graph[x].push_back(y);
graph[y].push_back(x);
}
vector<vector<vector<long long>>> memo(n, vector<vector<long long>>(k, vector<long long>(2, -1)));
auto dfs = [&](this auto&& dfs, int x, int fa, int cd, bool f){
auto& res = memo[x][cd][f];
if (res != -1) {
return res;
}
res = f ? -nums[x] : nums[x];
for (int y : graph[x]) {
if (y != fa) {
res += dfs(y, x, max(cd - 1, 0), f);
}
}
if (cd == 0) {
long long s = f ? nums[x] : -nums[x];
for (int y : graph[x]) {
if (y != fa) {
s += dfs(y, x, k - 1, !f);
}
}
res = max(res, s);
}
return res;
};
return dfs(0, -1, 0, 0);
}
};
感谢大家的点赞和关注,你们的支持是我创作的动力!(其他细节,有时间再补充...)