欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
今天是七月集训第五天:双指针🔥🔥🔥
// 541. 反转字符串 II
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.length();
for (int i = 0; i < n; i += 2 * k)
{
reverse(s.begin() + i, s.begin() + min(i + k, n));
}
return s;
}
};
// 392. 判断子序列
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.size(), m = t.size(), i = 0, j = 0;
while (i < n && j < m) {
if (s[i] == t[j]) //(1)
i++;
j++;
}
return i == n; //(2)
}
};
// 面试题 16.24. 数对和
class Solution {
public:
vector<vector<int>> pairSums(vector<int>& nums, int target) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end()); //(1)
int i = 0, j = nums.size() - 1;
while(i < j) {
int val = nums[i] + nums[j];
if(val > target) {
--j;
} else if(val < target) {
++i;
} else {
ans.push_back({nums[i], nums[j]}); //(2)
++i;
--j;
}
}
return ans;
}
};
// 696. 计数二进制子串
class Solution {
public:
int countBinarySubstrings(string s) {
vector<int> counts;
s += '-'; //(1)
int n = s.length();
int count = 1;
for(int i = 1; i < n; ++i) {
if(s[i] == s[i - 1]) {
count++;
} else {
counts.push_back(count);
count = 1;
}
} //(2)
int ans = 0;
for(int i = 1; i < counts.size(); ++i) {
ans += min(counts[i], counts[i - 1]);
} //(3)
return ans;
}
};
// 双指针
class Solution {
public:
int countBinarySubstrings(string s) {
s += '-';
int n = s.length();
int count = 1, prev = 0;
int ans = 0;
for(int i = 1; i < n; ++i) {
if(s[i] == s[i - 1]) {
count++;
} else {
ans += min(count, prev);
prev = count;
count = 1;
}
}
return ans;
} //(5)
};
"00110011
,这是题目的例子,这一步就是一次统计连续的0
或者1
的个数,放到counts数组中去,"00110011
这个例子应该很容易看出,2个0、2个1、2个0再接2个1,counts{2,2,2,2}
;counts[0]
和counts[1]
,得到的是2个0和2个1,即0011
,这里的贡献其实就是2种情况01
和0011
,即min(counts[0], counts[1])
,那么接下去遍历1100
贡献也是2,得到的是10
和1100
……所以推出每一个位置对答案的贡献是min(counts[i], counts[i - 1])
。00111011
,这样counts{2,3,1,2}
。接下去逐个去遍历counts,当2个0和3个1,最多贡献01
和0011
2种;当3个1和1个0,最多贡献10
1种;当1个0和2个1,最多贡献01
1种,最终就是4种情况。