寒假刷题Day26
一、2825. 循环增长使字符串子序列等于另一个字符串
class Solution {
public:
bool canMakeSubsequence(string str1, string str2) {
int i = 0, j = 0;
while(i < str1.size() && j < str2.size()){
// 计算递增后的字符(z会循环到a)
char next_char = (str1[i] == 'z') ? 'a' : str1[i] + 1;
// 两种可能的匹配方式
if (str1[i] == str2[j] || next_char == str2[j]){
j++;
}
i++;
}
return j == str2.size();
}
};
二、1023. 驼峰式匹配
class Solution {
public:
vector<bool> camelMatch(vector<string>& queries, string pattern) {
vector<bool> ans;
for(string word : queries){
int i = 0, j = 0;
while(i < word.size() && j < pattern.size()){
if(word[i] == pattern[j]) j++;
else if(isupper(word[i])) break;
i++;
}
bool match = (j == pattern.size());
// 如果模式串已经全部匹配,继续检查word剩余部分
while(match && i < word.size()){
if(isupper(word[i])){
match = false;
break;
}
i++;
}
ans.push_back(match);
}
return ans;
}
};
因为可能出现前面已经匹配完后,后面还插入了大写字母的情况,所以需要对word剩余部分再做遍历判断是否有大写字母。
isupper——判断是否是大写字母
islower——小写
isalpha——字母
isdigit——数字
三、3132. 找出与数组相加的整数 II
class Solution {
public:
int minimumAddedInteger(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
// 枚举可能的 x,对应保留部分的起始位置为 nums1[2], nums1[1], nums1[0]
for (int i = 2; i > 0; i--) {
int x = nums2[0] - nums1[i];
int j = i, k = 0; // j从i开始遍历,表示从保留部分开始
while (j < nums1.size() && k < nums2.size()) {
// 检查当前元素加上 x 是否正好等于 nums2[k],
if (nums1[j] + x == nums2[k])
k++;
j++;
}
// 如果成功匹配整个 nums2,则找到合法的 x
if (k == nums2.size())
return x;
}
return nums2[0] - nums1[0];
}
};
有种抽丝剥茧的感觉,寻找子数组的本质被隐藏在对x的枚举之下
四、522. 最长特殊序列 II
class Solution {
public:
int findLUSlength(vector<string>& strs) {
sort(strs.begin(), strs.end(), [](const string& a, const string& b) {
return a.length() > b.length(); // 按长度降序排序
});
unordered_map<string, int> freq;
for (const string& s : strs) freq[s]++; // 统计字符串频率
for (int i = 0; i < strs.size(); i++) {
if (freq[strs[i]] > 1) continue; // 如果字符串重复,直接跳过
for(int i = 0; i < strs.size(); i++){
bool ans = true;
for (int j = 0; j < strs.size(); j++) {
if (i != j && isSubseq(strs[i], strs[j])) {
ans = false;
break;
}
}
if (ans) return strs[i].length();
}
return -1;
}
private:
// a是否是b的子串,是返回true
bool isSubseq(const string& a, const string& b) {
if (a.size() > b.size()) return false; // 长度检查优化
int i = 0, j = 0;
while (i < a.size() && j < b.size()) {
if (a[i] == b[j]) i++;
j++;
}
return i == a.size();
}
};
1.只需要直接比较字符串之间是不是另一个字符串的子串,因为当自己是对方的子串,那自己的子串也肯定是对方的子串;
2.因为已经按长度降序排好了,所以当从左往右遍历查找,有一个字符串不是其他字符串的子串的时候就直接输出这个字符串的长度,它就是答案。