前言
欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
今天是六月集训第五天:双指针🔥🔥🔥
一、练习题目
二、算法思路
- 1、2000. 反转单词前缀:先遍历看看能不能找到目标字符,如果遍历完整一个字符串都找不到,就直接返回原串;如果找到我们记录下标位置为j,然后在 [ 0 , j ] [0,j] [0,j]范围内进行交换。🔥
- 2、917. 仅仅反转字母:五月集训做过了。🔥
- 3、475. 供暖器:这题和后面一题花了点时间,这两题的思路很像,思路是遍历每一个房子,二分的加热器数组中离得房子最近的一个加热器所需的范围,然后再返回最小范围中的最大值就是能够满足所有范围的那一个,是一个 m a x ( m i n ( ) ) max(min()) max(min())问题。这里要主要两边界最左和最右,他们的左端和右端都是无穷需要单独处理否则数组越界的。🔥🔥🔥🔥
- 4、面试题 16.06. 最小差:这题可以用上一题的思路,但是求的一个最小值。然后我用了一个双指针的方法来做。同时为了防止越界直接上long来处理了。🔥🔥🔥🔥
三、源码剖析
// 2000. 反转单词前缀]
class Solution {
public:
string reversePrefix(string word, char ch) {
int n = word.size();
int i, j = 0;
while(j < n) {
if(word[j] == ch) {
break;
}
j++;
}
if(j == n) {
return word;
}
for(i = 0; i < j; i++, j--) {
swap(word[i], word[j]);
}
return word;
}
};
- 1、简单题写在思路分析中。
// 917. 仅仅反转字母
class Solution {
public:
string reverseOnlyLetters(string s) {
int i = 0, j = s.length() - 1;
while(i < j) {
if(isalpha(s[i]) && isalpha(s[j])) {
swap(s[i], s[j]);
++i, --j;
} else if(!isalpha(s[i])) {
++i;
} else if(!isalpha(s[j])) {
--j;
} else {
++i, --j;
}
}
return s;
}
};
- 1、可以看五月集训的内容。
// 475. 供暖器
class Solution {
public:
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(houses.begin(), houses.end());
sort(heaters.begin(), heaters.end());
int x, ret = 0;
for(int i = 0; i < houses.size(); ++i) {
if(houses[i] < heaters[0]) {
x = heaters[0] - houses[i]; //(1)
} else if(houses[i] > heaters.back()) {
x = houses[i] - heaters.back();
} else {
int ans = -1;
int l = 0, r = heaters.size() - 1;
while(l <= r) {
int mid = (l + r) >> 1;
if(heaters[mid] <= houses[i]) {
l = mid + 1;
ans = mid;
} else {
r = mid - 1;
}
}
if(ans == heaters.size() -1) {
x = houses[i] - heaters[ans];
} else {
x = min(heaters[ans+1] - houses[i], houses[i] - heaters[ans]);
}
}
ret = max(x, ret);
}
return ret;
}
};
- 1、见算法思路。
// 面试题 16.06. 最小差
class Solution {
public:
int smallestDifference(vector<int>& a, vector<int>& b) {
sort(a.begin(), a. end());
sort(b.begin(), b. end()); //(1)
int n = a.size(), m = b.size(), i = 0, j = 0;
long ret = LONG_MAX;
while(i < n && j < m) {
if(a[i] != b[j]) { //(2)
ret = min(ret, (long)abs(a[i] - b[j]));
a[i] > b[j] ? j++ : i++;
} else {
return 0;
}
}
return ret;
}
};
- 1、先排序
- 2、两个不相等,就取绝对值,并与结果取最小值,比较当前数的大小,把小的那个指针往右移,因为要找差的最小值,尽量缩小差值。如果有数相等直接返回0,因为0肯定是最小的差值,这里有点贪心的思想。