携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
前言
两个月前兴致冲冲的立下flag,每天都要刷一道算法题🤓,然后就去 leetcode 逛了一下,满怀信心的点开了第一题🧐,过了5分钟,我点开了评论区,第一条神评:有人相爱,有人夜里开车看海,有人 leetcode 第一题都做不出来。😂是我没错了,然后就去了B站找了一些算法题的视频,后面发现直接看着视频学也不能完全理解,数据结构的基础,很多概念的东西都不能理解😖。万丈高楼平地起,所以地基还是需要打牢的,然后又去看数据结构的视频,这里推荐一本学习数据结构的书《学习JavaScript数据结构与算法(第3版)》。后面很长的时间都没有认真的静下心来学习数据结构与算法,今天在想写什么水文😂时,发现了这篇之前学算法时的笔记,又想起来两个月前立的flag到现在毫无进展,正好现在调整作息时间,早上有一点时间可以学习数据结构与算法,这段时间先把基础打牢吧😁
再推荐一个B站的视频 一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解
接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
二维蓄水
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5] 输出:9
从图中可以看出,每个位置的接水量,取决于左右两侧高度的最小值,需要向两侧依次遍历下去,才能确保找到最大的接水量。
-
第一步先找出左右两边的最高的柱子
-
用最高的柱子减去自身的高度
-
把所有单位储水量相加
方法一 暴力解法
function trap(height) {
const n = height.length;
if (n === 0) {
return 0;
}
let res = 0;
for (let i = 1; i < n - 1; i++) {
let l_max = 0;
let r_max = 0;
for (let j = i; j < n; j++) {
//找出右边最高的柱子
r_max = Math.max(r_max, height[j]);
}
for (let j = i; j >= 0; j--) {
//找出左边最高的柱子
l_max = Math.max(l_max, height[j]);
}
res += Math.min(l_max, r_max) - height[i];
}
return res;
}
console.log(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]));
方法二 数组解法
function trap(height = []) {
const n = height.length;
if (n === 0) {
return 0;
}
let res = 0;
let l_max = new Array(n);
let r_max = new Array(n);
l_max[0] = height[0];
r_max[n - 1] = height[n - 1];
//计算l_max,从左到右
for (let i = 1; i < n; i++) {
l_max[i] = Math.max(height[i], l_max[i - 1]);
}
//计算r_max,从右到左
for (let i = n - 2; i >= 0; i--) {
r_max[i] = Math.max(height[i], r_max[i + 1]);
}
for (let i = 1; i < n - 1; i++) {
res += Math.min(l_max[i], r_max[i]) - height[i];
}
return res;
}
console.log(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]));
方法三 双指针
function trap(height = []) {
const n = height.length;
if (n === 0) {
return 0;
}
let res = 0;
let left = 0;
let right = n - 1;
let l_max = height[0];
let r_max = height[n - 1];
while (left <= right) {
l_max = Math.max(l_max, height[left]);
r_max = Math.max(r_max, height[right]);
if (l_max < r_max) {
res += l_max - height[left];
left++;
} else {
res += r_max - height[right];
right--;
}
}
return res;
}
console.log(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]));