第一题
解题思路:先取前两个数之和作为目标值,然后从第三个位置开始每次往后遍历两个数,若与目标值相等则res加1,否则终止循环。
class Solution {
public:
int maxOperations(vector<int>& nums) {
int res = 1, target = nums[0]+nums[1], len = nums.size();
for(int i = 3; i < len && nums[i]+nums[i-1]==target; i+=2){
++res;
}
return res;
}
};
第二题
解题思路:可以知道最后一次操作之前的字符肯定是出现次数最多的字母,所以可以使用哈希表存储每个字母的出现次数,找出出现次数最大的值记为mx,然后从后往前遍历找出出现次数为mx的字母添加到结果集合中,最后返回翻转的结果集合。
class Solution {
public:
string lastNonEmptyString(string s) {
vector<int> cnt(26);
for(char c:s)
++cnt[c-'a'];
int mx = *max_element(cnt.begin(),cnt.end());
string res = "";
for(int i = s.size()-1; i >= 0; i--){
if(cnt[s[i]-'a'] == mx){
cnt[s[i]-'a'] = 0;
res.push_back(s[i]);
}
}
reverse(res.begin(),res.end());
return res;
}
};
第三题
解题思路:使用记忆化搜索的方式,有三种搜索方式,分别是取前两个元素之和作为target搜索,取最后两个元素之和作为target进行搜索,取第一个以及最后一个元素之和作为target进行搜索;搜索的终止条件是数组元素个数小于2个,搜索的情况也是分为三种,与上面三种情况一样。最后返回搜索结果的最大值。
class Solution {
public:
int maxOperations(vector<int>& nums) {
int n = nums.size();
int memo[n][n];
auto helper = [&](int i,int j,int target)->int{
memset(memo,-1,sizeof(memo));
function<int(int,int)> dfs = [&](int i,int j)->int{
if(i >= j) return 0;
int &res = memo[i][j];
if(res != -1) return res;
res = 0;
if(nums[i]+nums[i+1] == target) res = max(res,dfs(i+2,j)+1);
if(nums[j]+nums[j-1] == target) res = max(res,dfs(i,j-2)+1);
if(nums[i]+nums[j] ==target) res = max(res,dfs(i+1,j-1)+1);
return res;
};
return dfs(i,j);
};
int res1 = helper(2,n-1,nums[0]+nums[1]);
int res2 =helper(0,n-3,nums[n-1]+nums[n-2]);
int res3 = helper(1,n-2,nums[0]+nums[n-1]);
return max({res1,res2,res3})+1;
}
};
第四题
解题思路:首先进行排序,然后使用哈希表存储遍历数组元素的值,当将f[i]加1时,f[i+1]的状态为f[i]+1,当f[i]的值不变时,f[i]的状态为f[i-1]+1,最后取value的最大值即为最多可以选出的元素数目。
class Solution {
public:
int maxSelectedElements(vector<int>& nums) {
//sort(nums.begin(),nums.end());
ranges::sort(nums);
unordered_map<int,int> f;
for(int i:nums){
f[i+1] = f[i]+1;
f[i] = f[i-1]+1;
}
int res = 0;
for(auto &[_,num]:f){
res = max(res,num);
}
return res;
}
};