1488. Avoid Flood in The City
解题思路
本题的关键在于我们要怎么在同一个湖的下一场雨之前把湖水排干
为了这个目的我们需要提前做一些准备:
fullLakes:一个 Map,用来保存rains[i], i,记录之前的雨下在rains[i]湖的下标(日期)dryDays:数组,用来记录还未使用的没下雨的下标(日期),这样可以在将来下雨的时候用res:数组,用来保存答案
有了这些之后,我们的算法步骤如下:
遍历
rain数组如果当天没下雨,则将当前下标保存到
dryDays中,然后回到步骤 1- 如果当天下雨了,判断当前下雨的湖泊之前是否有下过雨(是否在
fullLakes中),如果有则在dryDays中寻找从上次下雨到现在范围内最早的dryDay放水;如果没有就把当前下雨的湖泊记录到fullLakes中 - 如果在
dryDays中找不到符合规则的时间,则返回空数组[]
题目描述有一点没有说清楚,如果当天没下雨,但是也没有需要放水的湖泊了,我们仍然需要选择一个 1~无限大的数字来填充进数组
不然这个 case 就会失败:
// testcase
[69,0,0,0,69]
// expect
[-1,69,1,1,-1]
下标 2、3 的数字不能是 -1。。。所以我们一开始给数组 res 要默认赋值 1
Javascript
/**
* @param {number[]} rains
* @return {number[]}
*/
var avoidFlood = function (rains) {
const res = new Array(rains.length).fill(1)
// {rains[i], i}
const fullLakes = new Map()
const dryDays = []
for (let i = 0; i < rains.length; i++) {
if (rains[i] === 0) {
dryDays.push(i)
} else {
res[i] = -1
if (fullLakes.has(rains[i])) {
const idx = binarySearch(dryDays, fullLakes.get(rains[i]))
if (idx === dryDays.length) {
return []
}
res[dryDays[idx]] = rains[i]
const dryIdx = dryDays.splice(idx, 1)
}
fullLakes.set(rains[i], i)
}
}
return res
};
const binarySearch = (arr, target) => {
let left = 0
let right = arr.length
while (left < right) {
let mid = (left + right) >> 1
if (arr[mid] <= target) {
left = mid + 1
} else {
right = mid
}
}
return left
}