42. Trapping Rain Water
1.暴力解法(未通过)
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
int res = 0;
for(int i=0; i<n; i++){
int r_max = 0, l_max= 0;
for(int j = i; j<n; j++)
r_max = max(r_max, height[j]);
for(int j=i; j>=0; j--)
l_max = max(l_max, height[j]);
res += min(r_max, l_max) - height[i];
}
return res;
}
};
解法的基本思路:
要把每一段拆分出来
某一竖条的储水量怎么求? 他的高度是左边最大 和 右边最大 取的最小值,然后再减去自身的高度
2.备忘录
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
int res = 0;
vector<int> r_max(n, 0);
vector<int> l_max(n, 0);
l_max[0] = height[0];
r_max[n-1] = height[n-1];
for(int i=1; i<n; i++)
l_max[i] = max(height[i], l_max[i-1]);
for(int i=n-2; i>=0; i--)
r_max[i] = max(height[i], r_max[i+1]);
for(int i=0; i<n; i++){
res += min(r_max[i], l_max[i]) - height[i];
}
return res;
}
};
这里就是把每一次的最大最小值都记录下来,就不用每次都遍历了,跟上一个思想没有区别
3.双指针法
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
int l_max = 0, r_max = 0;
int res = 0;
int left = 0, right = n-1;
while(left < right){
l_max = max(l_max, height[left]);
r_max = max(r_max, height[right]);
if(l_max < r_max){
res += l_max - height[left];
left++;
}else{
res += r_max - height[right];
right--;
}
}
return res;
}
};
这里的l_max是【0, left】的最大值,r_max是【right, n-1】的最大值
为什么这样可以呢?因为其实只要一边找到最大值了,无论另一边是不是最大值,只要比它大,那么一定能兜住他
58. Length of Last Word
class Solution {
public:
int lengthOfLastWord(string s) {
int res = 0;
int tail = s.size()-1;
while(tail >= 0 && s[tail] == ' ') tail--;
while(tail >=0 && s[tail] != ' '){
res++;
tail--;
}
return res;
}
};
因为最后也有可能有空格,所以从后面开始
14. Longest Common Prefix
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int n = strs.size();
string res = "";
sort(strs.begin(), strs.end());
string a = strs[0];
string b = strs[n-1];
int i=0;
while(i<a.size() && i<b.size()){
if(a[i] != b[i]) break;
res += a[i];
i++;
}
return res;
}
};
这里用到sort, sort的最前和最后是最不相关的两个string