六月集训(第05天)—双指针
双指针
1. 2000. 反转单词前缀
思路:
遍历找到ch出现的位置r,从0~r翻转word即可。
class Solution {
public:
string reversePrefix(string word, char ch) {
int word_len = word.length();
int l = 0, r = -1, i = 0;
for (i = 0; i < word_len; ++i) {
if (ch == word[i]) {
r = i;
break;
}
}
if (r == -1) return word;
while (l < r) {
swap(word[l++], word[r--]);
}
return word;
}
};
2. 917. 仅仅反转字母
思路:
利用l和r两个指针从字符串两端向中间遍历,l++直到s[l]是英文字母暂停,r--直到s[r]为英文字母暂停,交换s[l],s[r]后重复上述操作。
class Solution {
bool is_english(char ch) {
if (ch >= 'A' && ch <= 'Z') return true;
if (ch >= 'a' && ch <= 'z') return true;
return false;
}
public:
string reverseOnlyLetters(string s) {
int s_len = s.length();
int l = 0, r = s_len - 1;
while (l < r) {
if (!is_english(s[l])) ++l;
if (!is_english(s[r])) --r;
if (is_english(s[l]) && is_english(s[r])) {
swap(s[l], s[r]);
++l;
--r;
}
}
return s;
}
};
3. 475. 供暖器
思路:
对heaters[]排序后,对每个houses[i]二分查找小于houses[i]的最大下标idx
(1) house两边都有heaters : width_max为 max(width_max, min(houses[i] - heaters[idx], heaters[idx + 1] - houses[i]));
(2) house只有右边有heaters :即house在heaters[0]左边时,width_max = max(width_max, heaters[0] - houses[i]);
(3) house只有左边有heaters :即house在heaters[size - 1]右边时 在这里插入代码片
class Solution {
int find_nearest_less(int l, int r, int ans, vector<int> &heaters) {
int ret = 0;
while (l <= r) {
int mid = l + ((r - l) >> 1);
if (heaters[mid] <= ans) {
l = mid + 1;
ret = mid;
}
else r = mid - 1;
}
return ret;
}
public:
int findRadius(vector<int>& houses, vector<int>& heaters) {
int houses_size = houses.size(), heaters_size = heaters.size();
int i;
int width_max = 0;
sort(heaters.begin(), heaters.end());
for (i = 0; i < houses_size; ++i) {
if (houses[i] <= heaters[0]) { /* 没有比houses[0]小的元素 */
width_max = max(width_max, heaters[0] - houses[i]);
continue;
}
int idx = find_nearest_less(0, heaters_size - 1, houses[i], heaters);
if (idx == -1 || idx == heaters_size - 1) width_max = max(width_max, houses[i] - heaters[idx]); /* houses[i]比所有heaters[]都大,取heaters[size - 1]即可 */
else { /* 对于位于两个heaters之间的houses选择左右最近的heater即可 */
width_max = max(width_max, min(houses[i] - heaters[idx], heaters[idx + 1] - houses[i]));
}
}
return width_max;
}
};
4. 面试题 16.06. 最小差
思路:
思路同第三题,注意强转作差时强转long long否则int溢出。
class Solution {
#define ll long long
int find_idx_less(int l, int r, int ans, vector<int> &b) {
int ret = l;
while (l <= r) {
int mid = l + ((r - l) >> 1);
if (ans >= b[mid]) {
l = mid + 1;
ret = mid;
} else {
r = mid - 1;
}
}
return ret;
}
public:
int smallestDifference(vector<int>& a, vector<int>& b) {
int a_size = a.size(), b_size = b.size();
int i = 0, j = 0;
long long ans = INT_MAX;
sort(b.begin(), b.end());
for (i = 0; i < a_size; ++i) {
if (a[i] <= b[0]) {
ans = min(ans, ((ll)b[0] - (ll)a[i]));
continue;
}
int idx = find_idx_less(0, b_size - 1, a[i], b);
if (idx >= b_size - 1) ans = min(ans, ((ll)a[i] - (ll)b[b_size - 1]));
else ans = min(ans, min(((ll)a[i] - (ll)b[idx]), ((ll)b[idx + 1] - (ll)a[i])));
}
return ans;
}
};
东方欲晓,莫道君行早。

浙公网安备 33010602011771号