一觉惊醒 6:40,md,断了。
题目描述:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
思路:
用两个指针i,j分别指向字符串s和t;
因为要在t中找s的字符,所以如果s[i]和t[j]不相等时候,j往后走,相等则一起往后走;
最后判断i是否走到s字符串末尾,如果是,则返回true,否则返回false;
class Solution {
public:
bool isSubsequence(string s, string t) {
int i = 0, j = 0;
while (s[i] && t[j]) {
if (s[i] == t[j]) {
i++;
}
j++;
}
return s[i] == '\0';
// int i = 0, j = 0;
// while (i < s.size() && j < t.size()) {
// if (s[i] == t[j]) {
// ++i;
// }
// ++j;
// }
// if (i == s.size()) {
// return true;
// }
// return false;
}
};
题目描述:
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
思路:
根据题目意思,首先无论是否能计数到2k个数,前小于等于k个数肯定是要翻转的,那么重要的是判断需要翻转多少个数即可;
翻转函数可以自己写,也可以用库函数 reverse函数yyds;
class Solution {
void swap(char &a, char &b) {
char tmp = a;
a = b;
b = tmp;
}
public:
string reverseStr(string s, int k) {
int i;
int n = s.length();
int start, end;
for (i = 0; i < n; i += 2*k) {
start = i;
end = min(i + k - 1, n-1);
while (start < end) {
swap(s[start++], s[end--]);
}
}
return s;
// 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;
}
};
题目描述:
设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。
思路:
典型双指针题目;记得要先排序
class Solution {
public:
vector<vector<int>> pairSums(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int i = 0, j = nums.size() - 1;
vector<vector<int>> ans;
while (i < j) {
int sum = nums[i] + nums[j];
if (sum > target) {
j--;
} else if (sum < target) {
i++;
} else {
ans.push_back({nums[i], nums[j]});
i++;
j--;
}
}
return ans;
}
};
题目描述:
给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。
重复出现(不同位置)的子串也要统计它们出现的次数。
思路:
可以用双指针,也可用dp;
双指针:
首先找到第一个不与前面字符s[i]相等的字符s[j],记录下位置k;
然后找到最后一个不与前面字符相等的字符s[j],这个时候可以统计次数,这个次数取决于前后两个不相等字符串短的那个串的长度,即min(k-i,j-k)k-i表示前面那个字符串的长度,j-k表示后面那个字符串的长度;
dp:
先遍历字符串,用dp[i]表示统计出的前面到第i个位置能够得到的最长相等子串的长度;
然后令l = dp[i],表示第i个位置的有l个长度相等的子串,那么i-l位置处的字符必定于i处字符不相等,即s[i] != s[i-l],ll = dp[i-l]表示到i-l这个位置有ll个长度相等的字符串,当ll>l时,计数器加一;
class Solution {
// int dp[100010];
public:
int countBinarySubstrings(string s) {
int ans = 0;
int i = 0, j = 0;
while (j < s.length()) {
while (s[i] == s[j] && j < s.length()) {
++j;
}
int k = j;
while (s[i] != s[j] && j < s.length()) {
++j;
}
ans += min(j - k, k - i);
i = k;
}
return ans;
// int ans = 0;
// s = '#' + s;
// for (int i = 1; i < s.length(); ++i) {
// if (s[i] == s[i-1]) {
// dp[i] = dp[i-1] + 1;
// } else {
// dp[i] = 1;
// }
// }
// for (int i = 1; i < s.length(); ++i) {
// int l = dp[i]; // 前面有l个字符与s[i]字符相等
// int ll = dp[i - l]; // 字符s[i-l]与字符s[i]不相等
// if (ll >= l) {
// ans ++;
// }
// }
// return ans;
}
};