LeetCode 42. Trapping Rain Water

Python解法

解题思路:

本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程。

  1. 将每一个点的高度和索引存成一个元组 (val, idx)
  2. 找到最高的点(可能有多个,任取一个),记为 (now_val, now_idx)。
  3. 向左找第一个val不大于now_val的点(left_val, left_idx)。
  4. 以left_val作为水平面,用height[left_val+1, now_val-1]中每一个点更新ans。
  5. now_val, now_idx = left_val, left_idx。
  6. 如果now_idx >= 0 ,重复执行3;否则执行7。
  7. 同理从最高点向右遍历更新ans。

向左找的具体操作

  1. 将每一个点的高度和索引存成一个元组 (val, idx)
  2. 将元组按val从大到小排序,若val相等,按idx从大到小排序。实现过程:直接sort,然后reverse。
  3. 从左向右遍历,找到第一个idx小于now_idx的节点(left_val, left_idx),用height[left+1, now-1]中的点更新ans。
  4. 更新now节点为left节点。
  5. 如果now_idx >= 0 ,重复执行3;否则结束循环,开始向右找。

向右找的具体操作

  1. 将每一个点的高度和索引存成一个元组 (val, idx)
  2. 将元组按val从大到小排序,若val相等,按idx从小到大排序。实现过程:用functools中的cmp_to_key重载排序过程。
  3. 从左向右遍历,找到第一个idx大于now_idx的节点(right_val, right_idx),用height[now+1, right-1]中的点更新ans。
  4. 更新now节点为lright节点。
  5. 如果now_idx >= 0 ,重复执行3;否则执行6。
  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))的更多相关文章

  1. leetcode#42 Trapping rain water的五种解法详解

    leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...

  2. [array] leetcode - 42. Trapping Rain Water - Hard

    leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...

  3. LeetCode - 42. Trapping Rain Water

    42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...

  4. [LeetCode] 42. Trapping Rain Water 收集雨水

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  5. leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法

    Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...

  6. [leetcode]42. Trapping Rain Water雨水积水问题

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  7. [LeetCode] 42. Trapping Rain Water 解题思路

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  8. Java [Leetcode 42]Trapping Rain Water

    题目描述: Given n non-negative integers representing an elevation map where the width of each bar is 1, ...

  9. LeetCode 42 Trapping Rain Water(积水体积)

    题目链接: https://leetcode.com/problems/trapping-rain-water/?tab=Description   Problem: 根据所给数组的值,按照上图的示意 ...

随机推荐

  1. Jsp页面中常用的EL表达式

    首先引入标签 <%@ page language="java" contentType="text/html; charset=utf-8"  pageE ...

  2. Codeforces Round #550 (Div. 3)E. Median String

    把字符串看作是26进制的数,从后往前翻译,那么就可以把两个串变成对应的26进制的数字,那么只要把两个数加起来除以二就得到中间的串对应的数了,同理再转化回来就行了.但是这样会有一个问题就是串的长度有2e ...

  3. 使用canvas截图网页为图片并解决跨域空白以及模糊问题

    前几天给了个需求对浏览器网页进行截图,把网页统计数据图形表等截图保存至用户本地. 首先对于网页截图,我用的是canvas实现,获取你需要截图的模块的div,从而使用canvas对你需要的模块进行截图. ...

  4. PHP循环输出二维数组的数据

    //下面是一个例子$g_id = isset($_GET['id'])?$_GET['id']:'1';//定义变量$g_id,使用三元运算符是为了避免出现waring $p_id = ($g_id& ...

  5. 批量重命名B站下载文件

    将B站下载的文件统一修改文件名 事情来由 事情是这样的,我在B站上发现一个教程,看了一下,非常不错,于是想下载下来(免得B站和谐). 问题就是这样来了,我手机没多少内存,下载后下发现文件在手机中都是以 ...

  6. java的几种对象(PO,VO,DAO,BO,POJO)解释 (转)

    java的几种对象(PO,VO,DAO,BO,POJO)解释 一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中 ...

  7. 2.IntelliJ IDEA 下载破解(2017)

    1.首先,我找到了 IntelliJ IDEA的官网:www.jetbrains.com 然后找到下载的地方,选择自己电脑所匹配的下载安装包,这里我们选择收费版的下载,因为免费版的功能并没有收费版的强 ...

  8. win7下qt+opencv的环境配置

    博客http://blog.csdn.net/qiurisuixiang/article/details/8665278已经完整地介绍了整个环境配置.需要一步不差按原执行.需要说明的是,几个path的 ...

  9. 0807再整理SQL执行流程

    转自http://www.cnblogs.com/annsshadow/p/5037667.html MySQL架构总览->查询执行流程->SQL解析顺序   前言: 一直是想知道一条SQ ...

  10. ZOJ 3209

    精确覆盖 #include <iostream> #include <cstdio> #include <cstring> #include <algorit ...