LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))
LeetCode 42. Trapping Rain Water
Python解法
解题思路:
本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程。
- 将每一个点的高度和索引存成一个元组 (val, idx)
- 找到最高的点(可能有多个,任取一个),记为 (now_val, now_idx)。
- 向左找第一个val不大于now_val的点(left_val, left_idx)。
- 以left_val作为水平面,用height[left_val+1, now_val-1]中每一个点更新ans。
- now_val, now_idx = left_val, left_idx。
- 如果now_idx >= 0 ,重复执行3;否则执行7。
- 同理从最高点向右遍历更新ans。
向左找的具体操作
- 将每一个点的高度和索引存成一个元组 (val, idx)
- 将元组按val从大到小排序,若val相等,按idx从大到小排序。实现过程:直接sort,然后reverse。
- 从左向右遍历,找到第一个idx小于now_idx的节点(left_val, left_idx),用height[left+1, now-1]中的点更新ans。
- 更新now节点为left节点。
- 如果now_idx >= 0 ,重复执行3;否则结束循环,开始向右找。
向右找的具体操作
- 将每一个点的高度和索引存成一个元组 (val, idx)
- 将元组按val从大到小排序,若val相等,按idx从小到大排序。实现过程:用functools中的cmp_to_key重载排序过程。
- 从左向右遍历,找到第一个idx大于now_idx的节点(right_val, right_idx),用height[now+1, right-1]中的点更新ans。
- 更新now节点为lright节点。
- 如果now_idx >= 0 ,重复执行3;否则执行6。
- 输出ans。
注意:向左向右只有排序不同,其他操作类似,
利用functools中的cmp_to_key重载排序过程代码如下:
def mcmp(a, b):
val1,idx1 = a
val2,idx2 = b
if val1 == val2:
return idx2-idx1
return val1-val2
from functools import cmp_to_key
l = [] # l中存元组(val, idx)
l.sort(reverse=True, key=cmp_to_key(Solution.mcmp))
代码如下
class Solution:
# 利用functools中的cmp_to_key重载排序:
def mcmp(a, b):
val1,idx1 = a
val2,idx2 = b
if val1 == val2:
return idx2-idx1
return val1-val2
def trap(self, height: List[int]) -> int:
if len(height) == 0:
return 0
from functools import cmp_to_key
l = []
# 将(val, idx)存入l = []中
for i in range(0, len(height)):
l.append((height[i],i))
ans = 0
# 往左找
l.sort(reverse=True)
h, con = l[0]
for i in range(1, len(l)):
val, left = l[i]
if left < con:
for j in range(left+1, con):
ans += val - height[j]
con = left
# 往右找
h, con = l[0]
l.sort(reverse=True, key=cmp_to_key(Solution.mcmp))
for i in range(1, len(l)):
val, right = l[i]
if right > con:
for j in range(con+1, right):
ans += val - height[j]
con = right
return ans
C++解法
解题思路:
本思路与Python类似,需找到最高点左右遍历,时间复杂度O(nlogn)以下为向左遍历的过程。差别在于C++是存map,无须手动排序。
// m中first存高度val,second存索引集合。
// set<int> s = m[2]表示高度为2的点的位置集合。
map<int, set<int>> m;
实现代码如下:
class Solution {
public:
int trap(vector<int>& height) {
if(height.size() == 0) return 0;
int ans = 0;
// m中first存高度val,second存索引集合。
// set<int> s = m[2]表示高度为2的点的位置集合。
map<int, set<int>> m;
// itm表示m的一个迭代器
map<int, set<int>>::iterator itm;
set<int> s;
set<int>::iterator its;
//将(val, idx)存入map
int sz = height.size();
for(int i = 0;i < sz; ++i){
m[height[i]].insert(i);
}
//向左找
itm = --m.end();
s = itm->second;
int h = itm->first;
int left = *s.begin();
//每次找val小,idx小的
while(left != -1 && left >= 0){
s = m[h];
its = s.lower_bound(left);
if(its == s.begin()){
if(itm == m.begin()){
left = -1;
}else{
--itm;
h = itm->first;
}
}else{
--its;
for(int i = *its+1;i < left; ++i){
ans += h-height[i];
}
left = *its;
continue;
}
}
//向右找
itm = --m.end();
s = itm->second;
h = itm->first;
int right = *s.begin();
//每次找val小,idx大的
while(right != -1 && right < sz){
s = m[h];
its = s.upper_bound(right);
if(its == s.end()){
if(itm == m.begin()){
right = -1;
}else{
--itm;
h = itm->first;
}
}else{
for(int i = right+1;i < *its; ++i){
ans += h-height[i];
}
right = *its;
continue;
}
}
return ans;
}
};
LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))的更多相关文章
- leetcode#42 Trapping rain water的五种解法详解
leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...
- [array] leetcode - 42. Trapping Rain Water - Hard
leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...
- LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...
- [LeetCode] 42. Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法
Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...
- [leetcode]42. Trapping Rain Water雨水积水问题
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [LeetCode] 42. Trapping Rain Water 解题思路
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- Java [Leetcode 42]Trapping Rain Water
题目描述: Given n non-negative integers representing an elevation map where the width of each bar is 1, ...
- LeetCode 42 Trapping Rain Water(积水体积)
题目链接: https://leetcode.com/problems/trapping-rain-water/?tab=Description Problem: 根据所给数组的值,按照上图的示意 ...
随机推荐
- 团体程序设计天梯赛-练习集-L1-047. 装睡
L1-047. 装睡 你永远叫不醒一个装睡的人 —— 但是通过分析一个人的呼吸频率和脉搏,你可以发现谁在装睡!医生告诉我们,正常人睡眠时的呼吸频率是每分钟15-20次,脉搏是每分钟50-70次.下面给 ...
- H3C交换机配置常用命令(转)
1.配置文件相关命令 [Quidway]display current-configuration //显示当前生效的配置 [Quidway]display saved-configuration / ...
- Python数据分析----scipy稀疏矩阵
一.sparse模块: python中scipy模块中,有一个模块叫sparse模块,就是专门为了解决稀疏矩阵而生.本文的大部分内容,其实就是基于sparse模块而来的 导入模块:from scipy ...
- 【剑指Offer】56、删除链表中重复的结点
题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4-> ...
- 如何解决windows docker共享目录不支持符号链接(do not support symlinks)?
windows使用docker toolbox,搭建前端开发环境时,在共享目录使用npm安装前端依赖时,发现报错,无法使用符号连接. 这里有一个帖子专门讨论这个问题,感兴趣可以看一下: https:/ ...
- #MySQL数据库无法远程访问的问题
在 Ubuntu上装了mysql,因为项目的数据库是mysql,将项目放在tomcat里面webapp下面,一直启动不成功.本来一直以为是jdbc驱动问题,后来发现不是. 感谢!!http://blo ...
- 一种脱离VC编程软件的方法学习C/C++编程(搭建EditPlus实现在文本编辑框中执行.c文件
网上下载一个EditPlus记事本安装好后就可以按照下面步骤进行搭建环境了: 一.工具(Tools)→配置用户工具(Configure UserTools...),[添加工具](Add Tool> ...
- JavaSE 学习笔记之封装(四)
封 装(面向对象特征之一):是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处:将变化隔离:便于使用:提高重用性:安全性. 封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共 ...
- (23)Spring Boot启动加载数据CommandLineRunner【从零开始学Spring Boot】
[Spring Boot 系列博客] )前言[从零开始学Spring Boot] : http://412887952-qq-com.iteye.com/blog/2291496 )spring bo ...
- Cloudera 5.8.3 SolrCloud+HDFS的索引数据备份和恢复。(需重启solr进程。)
一.备份基于HDFS的solrCloud集合数据 1.确认要备份的solr文件夹. /solr/history_customer_collection_test 2.开启HDFS快照功能. hdfs ...