算法总结(1)--最大储水量相关算法题(栈,优先队列模拟)
来源:互联网 发布:mac怎么裁剪音乐 编辑:程序博客网 时间:2024/04/27 15:16
最大储水量相关算法题
在leetcode,牛客网上类似的题目比较多,主要用到了栈,还有就是一些求解思路的问题(去掉一些无用的结果),这样降低时间复杂度
==
涉及到动态规划,栈模拟,优先队列等,主要是如何舍弃一些无用的结果
考虑时间复杂度从O(n^2)降到O(nlogn)再到O(n)等,包括使用hash
直方图内最大矩形
题目地址:
http://www.nowcoder.com/practice/13ba51c3fec74b58bbc8fa8c3eedf877?tpId=49&tqId=29284&rp=1&ru=/ta/2016test&qru=/ta/2016test/question-ranking
题目描述
有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。
给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
测试样例:
[2,7,9,4,1],5
返回:14
求解
求直方图矩形面积的最大值就是求数组中相邻元素(单个元素,两两相邻,三三相邻。。。 )中最小值乘以他们的数量得到面积,再取最大值,
可以直接O(n^2)求解,找到前面的位置和后面一个位置
利用栈,维持一个递增序列,当遇到小的直方图后,回退,依次求解
ac代码:
class MaxInnerRec {public: // 2 7 9 4 1 ,5 返回 14 int countArea(vector<int> A, int n) { if(n == 0) return 0; int maxVal = A[0]; stack<int> sta; sta.push(A[0]); for (int i = 1; i < n; i++) { int topVal = sta.top(); if (A[i] > topVal) { sta.push(A[i]); } else{ int cnt = 0; while (!sta.empty() && sta.top() > A[i]) { cnt++; int popVal = sta.top(); sta.pop(); int popMax = popVal*cnt;// 9 * 1, 7 * 2 if (popMax > maxVal) { maxVal = popMax; } } // 2 7 9 4 变成 2 4 4 4 // 2 4 4 4 1 变成 1 1 1 1 1, 计算出4*1, 4*2, 4*3, 2*4 for (int j = 0; j < cnt + 1; j++) sta.push(A[i]); } } int cnt = 0; while(!sta.empty()) { cnt ++; int popVal = sta.top(); sta.pop(); int popMax = popVal*cnt; if (popMax > maxVal) { maxVal = popMax; } } return maxVal; }};
11. Container With Most Water
题目地址
https://leetcode.com/problems/container-with-most-water/
题目描述
Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
求解思路
找两条竖线,与x轴组成一个容器,能存水的最大值
采用前后指针法
class Solution {public: int maxArea(vector<int> &height) { int i = 0; int j = height.size() - 1; int ans = 0; while (i < j) { int area = (j - i) * min(height[i], height[j]); ans = max(ans, area); // 舍弃短的,知道两条竖线相遇 if (height[i] <= height[j]) i++; else j--; } return ans; }};
42. Trapping Rain Water
题目地址
https://leetcode.com/problems/trapping-rain-water/
题目描述
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
求解思路
利用栈,大致思路是,在栈上维持一个最大值,如果比当前最大值小的全部入栈,遇到大的,可以进行一次存储水了,然后更新最大值继续操作。最后如果栈不为空,需要按照原来的思路,反过来再对其求解。最后可得到最终结果
class Solution {public: int trap(vector<int>& height) { int len = height.size(); if (len < 3) return 0; stack<int> sta; sta.push(height[0]); int maxH = height[0]; int ans = 0; for (int i = 1; i < len; i++){ if (height[i] < maxH){ sta.push(height[i]); } else{ // while (!sta.empty()){ int val = sta.top(); sta.pop(); ans += maxH - val; } sta.push(height[i]); maxH = height[i]; } } stack<int> sta2; if (!sta.empty()){ maxH = sta.top(); sta.pop(); sta2.push(maxH); } while (!sta.empty()){ int tmp = sta.top(); sta.pop(); if (tmp < maxH){ sta2.push(tmp); } else{ // while (!sta2.empty()){ int val = sta2.top(); sta2.pop(); ans += maxH - val; } sta2.push(tmp); maxH = tmp; } } return ans; }};
407. Trapping Rain Water II
题目地址:
https://leetcode.com/problems/trapping-rain-water-ii/
题目描述
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.
Note:
Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000.
Example:
Given the following 3x6 height map:
[ [1,4,3,1,3,2], [3,2,1,3,2,4], [2,3,3,2,3,1]]
Return 4.
在上一题的基础上,变成了一个三维的。
求解思路
维持一个优先队列,每次都取高度最低的那个,从外围到内,队列的出队列和入队列,确保所有位置都能试探一遍,然后添加访问标识,并在求解过程中修改高度值
ac代码
// 代码参考:http://blog.csdn.net/MebiuW/article/details/52664669?locationNum=1class Cell{public: int x, y, h; Cell(int _x, int _y, int _height){ x = _x; y = _y; h = _height; }};struct cmp{ bool operator()(Cell c1, Cell c2) { return c1.h > c2.h; }};class Solution {public: int trapRainWater(vector<vector<int>>& heightMap) { int m = heightMap.size(); if (m == 0) return 0; int n = heightMap[0].size(); if (n == 0) return 0; priority_queue<Cell,vector<Cell>,cmp> pq; // 每次取出的都是高度最小的 vector<vector<bool>> vis; vis.resize(m, vector<bool>(n,false)); //a.resize(m, vector<int>(n)); for (int i = 0; i < m; i++){ vis[i][0] = true; vis[i][n-1] = true; Cell c1(i, 0, heightMap[i][0]); Cell c2(i, n-1, heightMap[i][n-1]); pq.push(c1); pq.push(c2); } for (int j = 0; j < n; j++) { vis[0][j] = true; vis[m-1][j] = true; Cell c1(0, j, heightMap[0][j]); Cell c2(m-1, j, heightMap[m-1][j]); pq.push(c1); pq.push(c2); } int ans = 0; int dir[][2] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; while (!pq.empty()) { Cell cell = pq.top(); pq.pop(); for (int i = 0; i < 4; i++) { int nx = cell.x + dir[i][0]; int ny = cell.y + dir[i][1]; if (nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny]) { vis[nx][ny] = true; ans += max(0, cell.h - heightMap[nx][ny]); // 这里注意 Cell ctmp(nx, ny, max(heightMap[nx][ny], cell.h)); pq.push(ctmp); } } } return ans; }};
- 算法总结(1)--最大储水量相关算法题(栈,优先队列模拟)
- 数据结构1:栈、队列、优先队列相关的算法题
- 算法导论-----最大优先队列
- 最大优先队列--【算法导论】
- 算法入门--最大堆实现优先队列
- <C/C++算法>最大优先队列
- 堆排序算法以及最大优先队列
- 算法(2.4 优先队列)
- [算法学习笔记]基于最大堆实现最大优先队列
- 算法导论 第六章优先队列总结
- 算法笔记(堆实现的最大优先队列)
- 算法----优先队列
- 算法之优先队列
- 《算法导论》优先队列
- Javascript数据结构算法之队列(舞伴分配,基数排序,模拟优先就诊病人)
- 最短路算法(Dijsktra + 优先队列)
- Dijkstra算法 用优先队列(思路)
- 数据结构与算法(3)--优先队列
- 如何判断JVM内存泄露
- NYOJ 880 还是打印菱形
- RecycleView隐藏部分Item
- Linux df和du不一致问题排查
- SPOJ DQUERY - D-query
- 算法总结(1)--最大储水量相关算法题(栈,优先队列模拟)
- java后台调用HttpURLConnection类模拟浏览器请求实例(可用于接口调用)
- JSP里ContentType ,charset和pageEncoding的理解与区别
- 【高数】极限运算法则+两个重要极限
- PYTHON解析JSON学习
- RecyclerView 的IndexOutOfBoundsException: Inconsistency detected异常解决办法
- javaScript之鼠标操作(onmouseover)
- 大型网站架构之分布式消息队列
- 一维RMQ