【算法】水坑 深信服笔试第一题

当时没有写出来,脑子完全懵逼状态。我恨我自己。

求木板中间最大的容水量
其实就一左一右两个指针,保存左高度maxleft,右边高度maxright,如果左的小,就向右移,因为此时右边肯定比左边的大,可以堵住水,如果当前的高度比maxleft小,则有坑,可以计算出此时可以装入的水(maxleft-height[i])。如果比maxleft大,则不能装入水,但要更新maxleft,maxleft和maxright都是保存两边最高的边。
右边也一样。

#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
using namespace std;
int trap(vector<int>& height){
	vector<int> dp(height.size());
	int l = 0, r = height.size() - 1;
	int result = 0;
	int ml = 0;
	int mr = 0;
	while (l < r){
		if (height[l] < height[r]){
			if (ml < height[l])
			 ml = height[l];
			result += ml;
			++l;
		}
		else{
			if (mr < height[r])
				 mr = height[r];
			result += mr;
			--r;
		}
	}
	return result;
}
int main(int argc, char* argv[]) {
	
	int T;
	cin >> T;
	vector<int> result;
	while (T--){
		int n;
		cin >> n;
		vector<int> height(n);
		for (int i = 0; i < n; ++i){
			cin >> height[i];
		}

		cout << trap(height) << endl;
	}
	 
}

注意与下面的题目的差别

就是leetcode011 Trapping Rain Water和LeetCode 407. Trapping Rain Water II
这两种是坑,上面那个木板。就是因为做过这两道题,想在这个基础上面改,没有好好去理解题意,结果还不如重新写。脑子有坑,装得都是水。
leetcode011


#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
using namespace std;
int trap(vector<int>& height){
	vector<int> dp(height.size());
	int l = 0, r = height.size() - 1;
	int result = 0;
	int ml = 0;
	int mr = 0;
	while (l < r){
		if (height[l] < height[r]){
			if (ml > height[l])
				result += (ml - height[l]);
			else ml = height[l];
			++l;
		}
		else{
			if (mr > height[r])
				result += (mr - height[r]);
			else mr = height[r];
		}
	}
	return result;
}
int main(int argc, char* argv[]) {
	
	int T;
	cin >> T;
	vector<int> result;
	while (T--){
		int n;
		cin >> n;
		vector<int> height(n);
		for (int i = 0; i < n; ++i){
			cin >> height[i];



		}

		cout << trap(height) << endl;
	}
	 
}



leetcode407

#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
 
using namespace std;
//保存地图信息
struct qitem{
	int i;
	int j;
	int h;
	qitem(int _i, int _j, int _h):i(_i), j(_j), h(_h){};
};
//从小到大排列
struct cmp{
	bool operator()(const qitem& a, const qitem& b){
		return a.h > b.h;
	}
};
int cal(vector<vector<int>>& heightMap){

	priority_queue<qitem, vector<qitem>, cmp> pq;
	int rows = heightMap.size();
	if (rows <= 1) return 0;
	int cols = heightMap[0].size();
	//push地图四周的数据
	vector<vector<int>> visited(rows, vector<int>(cols, 0));
	for (int i = 0; i < rows; ++i){
		visited[i][0] = 1;
		pq.push( qitem(i, 0, heightMap[i][0]));
		visited[i][cols-1] = 1;
		pq.push(qitem(i, cols - 1, heightMap[i][cols - 1]));
	}
	for (int j = 1; j < cols - 1; ++j){
		visited[0][j] = 1;
		pq.push(qitem(0, j, heightMap[0][j]));
		
		visited[rows - 1][j] = 1;
		pq.push(qitem(rows - 1, j, heightMap[rows - 1][j]));
	}
	///浸水过程 扩展上下左右四个方向
	int dx[] = { 0, 0, -1, 1 };
	int dy[] = { 1, -1, 0, 0 };
	int result = 0;
	while (!pq.empty()){
		int i = pq.top().i;
		int j = pq.top().j;
		int h = pq.top().h;
		pq.pop();
		for (int k = 0; k < 4; ++k){
			int tempi = i + dx[k];
			int tempj = j + dy[k];
			if (tempi > 0 && tempi < rows - 1 && tempj>0 && tempj < cols-1&&visited[tempi][tempj]!=1){
				if (heightMap[tempi][tempj] < h){//如果周围有比当前矮的位置,则有坑,加水
					result += (h - heightMap[tempi][tempj]);
					heightMap[tempi][tempj] = h;//保存为加水后的高度
				}
				visited[tempi][tempj] = 1;
				pq.push(qitem(tempi, tempj, heightMap[tempi][tempj]));
			}
		}


	}

	return result;
};
int main(int argc, char* argv[]) {
	

	vector<vector<int>> heightMap = { { 1, 4, 3, 1, 3, 2 }, { 3, 2, 1, 3, 2, 4 }, { 2, 3, 3, 2, 3, 1 } };
	//trap(heightMap);
	cout << cal(heightMap) << endl;
 
		return 0;
}

猜你喜欢

转载自blog.csdn.net/chen_xinjia/article/details/82814542