- 按行处理
这个方法是自己想到的,但是会超时,一共315个测试用例只能通过314个,但是思路是没有问题的。一行一行的考虑,时间复杂度O(n*m)(其中m是数组中最大的数字)
class Solution {
public:
int trap(vector<int>& height) {
bool judge = true;
int sum = 0;
int size = height.size();
int temp;
while(judge){
int i = 0;
while(i < size && height[i] == 0) ++i;
if(i == size) judge = false;
while(i < size){
while(i < size && height[i] > 0){
height[i]--;
i++;
}
temp = 0;
while(i < size && height[i] == 0){
temp++;
i++;
}
if(i < size && temp != 0){
sum += temp;
}
}
}
return sum;
}
};
- 按列处理
思路:height[start ,,, maxIndex ,,,end],其中height[maxIndex]是这个数组中的最大值,现在只考虑maxIndex左边的部分,右边的部分类似。在height[start,,,,maxIndex - 1]中找到最大的数的index记为leftMaxIndex,则height[leftMaxIndex,,,,maxIndex ]中的积水量可以计算得出,依次向左执行上述操作,直到遍历完所有左边的数组,右面的数组类似,具体看代码。
时间复杂度O(n*n),空间复杂度O(1) 。
class Solution {
public:
int getMaxIndex(vector<int>& height, int start, int end){
if(start == end) return -1;
int max = start;
for(int i = start + 1; i < end; ++i){
if(height[i] > height[max]){
max = i;
}
}
return max;
}
int trap(vector<int>& height) {
int sum = 0;
int size = height.size();
int firstMaxIndex = getMaxIndex(height, 0, size);
if(firstMaxIndex != -1){
//计算左边能积多少水
int right = firstMaxIndex;
int leftMaxIndex = getMaxIndex(height, 0, firstMaxIndex);
while(leftMaxIndex != -1){
for(int i = leftMaxIndex + 1; i < right; ++i){
sum += (height[leftMaxIndex] - height[i]);
}
right = leftMaxIndex;
leftMaxIndex = getMaxIndex(height, 0, right);
}
//计算右边能积多少水
int left = firstMaxIndex;
int rightMaxIndex = getMaxIndex(height, left + 1, size);
while(rightMaxIndex != -1){
for(int i = left + 1; i < rightMaxIndex; ++i){
sum += (height[rightMaxIndex] - height[i]);
}
left = rightMaxIndex;
rightMaxIndex = getMaxIndex(height, left + 1, size);
}
}
return sum;
}
};
- 双指针
这种方法的时间复杂度可以达到O(N)
class Solution {
public:
/**
* max water
* @param arr int整型vector the array
* @return long长整型
*/
long long maxWater(vector<int>& arr) {
// write code here
int size = arr.size();
if(size == 0) return 0;
long long ans = 0;
int leftmax = arr[0];
int rightmax = arr[size - 1];
int i = 0, j = size - 1;
while(i <= j){
if(leftmax < rightmax){
if(arr[i] < leftmax){
ans += leftmax - arr[i];
}else{
leftmax = arr[i];
}
i++;
}else{
if(arr[j] < rightmax){
ans += rightmax - arr[j];
}else{
rightmax = arr[j];
}
j--;
}
}
return ans;
}
};