核心思想:该题最难的部分就是理解 “扩张” 操作:假设有两个字符相同的连续段 a 和 b,如何判断是否能扩展 b -> a;
当 a 和 b 长度相同,定义为可扩张;
当 a 和 b 长度不同,根据「a 和 b 长度对比」以及「a 的长度大小」分情况讨论:
当 b > a,不可扩张;
当 a > b,我们不一定要拿整一段的 b 进行扩张,可以拿 b 中的一个字符进行扩张。 因此只需要满足 a 扩张后的长度大于等于 3 即可定义为可扩张。
代码
class Solution {
public:int expressiveWords(string s, vector<string>& words) {// 时间复杂度:O(n * m + ∑(word[i].size()))// 空间复杂度:O(1)int n = s.size();int ans = 0;for(string word : words){int m = word.size(),i = 0,j = 0;// word 为模版字符串,s 为扩展字符串while(i < n && j < m){if(s[i] != word[j]) break;// 字母不相等// 分别找到 s,word 连续相同字符长度 a,bint a = i,b = j;while(a < n && s[a] == s[i]) a ++;while(b < m && word[b] == word[j]) b ++;a -= i,b -= j;// 如果长度不相等,且扩展的长度 a < b 模版长度,不可扩展// 如果扩展长度 a < 3,也不可扩展if(a != b && (a < b || a < 3)) break;// 更新指针,继续遍历下一个元素i += a,j += b;}if(i == n && j == m) ans ++;}return ans;}
};
3.最小差
题目
解析
核心思想:两个序列数字进行比较,数字更小的指针移动;
代码
class Solution {typedef long long ll;
public:int smallestDifference(vector<int>& a, vector<int>& b) {// 时间复杂度:O(nlogn + mlogm)// 空间复杂度:O(1)int n = a.size(),m = b.size();ll ans = INT_MAX;sort(a.begin(),a.end());sort(b.begin(),b.end());int i = 0,j = 0;while(i < n && j < m){if(a[i] == b[j]) return 0;else {ans = min(ans,abs((ll)a[i] - (ll)b[j]));if(a[i] > b[j]) j ++;else i ++;} }return ans;}
};