541. 反转字符串 II
代码/思路
思路:拿到字符串,我们以每次2 * k 的距离从头到尾进行遍历;
每次遍历,就在 2 * k 的子串长度内反转 k 长度的子串,如果这次遍历的长度小于2 * k,那么就在整个子串进行反转 k 长度子串的操作。
void swap(char *a, char *b)
{
char t = *a;
*a = *b;
*b = t;
}
/*
反转思路:双指针,分别指向头和尾 依次进行交换
*/
void reverse(char* l, char* r)
{
while(l < r)
{
swap(l++, r--);
}
}
int min(int a, int b)
{
return a < b ? a : b;
}
/*
思路:模拟
每计数 2k 个字符就反转这 2k 个字符的前 k 个字符;
所以循环时 i += 2 * k
每次反转操作 就看下 前 k 个字符的长度 和 字符总长谁更短
选择更短的进行反转操作
*/
char * reverseStr(char * s, int k){
int n = strlen(s);
for(int i = 0; i < n; i += 2 * k)
{
reverse( &s[i], &s[min(i + k - 1, n - 1)] );
}
return s;
}
技巧
反转一个字符串
392. 判断子序列
代码/思路
class Solution {
public:
bool isSubsequence(string s, string t) {
/*
定义两个指针 i, j 分别指向 s 和 t 中的每一个元素
看 i 和 j 号元素是否相等
如果相等则 i j 都 ++
否则 j++
最后看 i 指向的数组元素是否遍历完
*/
int i = 0, j = 0;
//只要指针还指向元素
while(s[i] && t[j])
{
if(s[i] == t[j])
{
i++;
}
//每次遍历都让j++
j++;
}
//最后看有没有遍历完s数组
return s[i] == '\0';
}
};
面试题 16.24. 数对和
代码/思路
class Solution {
public:
vector<vector<int>> pairSums(vector<int>& nums, int target) {
/*
先把这个数组进行排序
然后定义两个指针,分别指向头和尾元素
用val 保存 头尾指针的和 并与目标值target比较
*/
sort(nums.begin(), nums.end());
int i = 0;
int j = nums.size() - 1;
vector<vector<int>> ans;
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]} );
i++;
j--;
}
}
return ans;
}
};
696. 计数二进制子串
代码/思路
int countBinarySubstrings(char * s){
/*
思路:因为0 和 1 都是连续出现的,所以我们统计每次连续的0 或者 1 的个数存入count数组
然后在count数组中累加相邻的俩个元素中的最小者到res中就是最后的答案
*/
int f = 0;
int n = strlen(s);
int count[n];
int num = 0;
memset(count, 0, sizeof(count));
//统计每次连续的0 或者 1 的个数存入count数组
while(f < n)
{
int index = 0;
char temp = s[f];
while(f < n && temp == s[f])
{
index++;
f++;
}
count[num++] = index;
}
//在count数组中累加相邻的俩个元素中的最小者到res中
int res = 0;
for(int i = 1; i < num; i++)
{
res += fmin(count[i], count[i - 1]);
}
return res;
}