Avoid Flood in The City - Complete Solution Guide
Avoid Flood in The City is LeetCode problem 1488, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Your country has an infinite number of lakes. Initially, all the lakes are empty, but when it rains over the nth lake, the nth lake becomes full of water. If it rains over a lake that is full of water , there will be a flood . Your goal is to avoid floods in any lake. Given an integer array rains where: rains[i] > 0 means there will be rains over the rains[i] lake. rains[i] == 0 means there are no rains this day and you can choose one lake this day and dry it . Return an array ans where: ans.len
Detailed Explanation
The problem requires us to determine a sequence of actions to avoid floods in a system of lakes. We are given an array `rains` where `rains[i] > 0` indicates rain in lake `rains[i]` on day `i`, and `rains[i] == 0` means we can dry a lake on day `i`. Our task is to return an array `ans` of the same length as `rains`, where `ans[i] == -1` if it rained on day `i`, and `ans[i]` is the lake we choose to dry if it didn't rain. If we cannot avoid a flood, we return an empty array.
Solution Approach
The solution uses a greedy approach along with a priority queue to determine which lake to dry when `rains[i] == 0`. The algorithm first precomputes the next day each lake will be rained on and stores it in `next_rain_at`. Then, it iterates through `rains`. If it rains, it marks the lake as full. If it does not rain, it checks if there are any lakes that are full and will rain in the future. It uses a min-heap (priority queue) `lakes_to_dry` to store these lakes, ordered by the next rain date. When a dry day (`rains[i] == 0`) occurs, the algorithm picks the lake from the min-heap that will be rained on soonest, and removes the lake from full_lakes set. If at any point a lake is rained on while full, the algorithm immediately returns an empty array to signify a flood is unavoidable.
Step-by-Step Algorithm
- Step 1: Precompute the `next_rain_at` array: For each lake `rains[i]`, store the next index `j > i` where it will rain on the same lake. If a lake is never rained on again, store a large value (infinity) to indicate this.
- Step 2: Initialize necessary data structures: `ans` array to store the results, `full_lakes` to track full lakes, and `lakes_to_dry` (min-heap) to store lakes to be dried, prioritizing lakes that will rain sooner.
- Step 3: Iterate through the `rains` array:
- a. If `rains[i] > 0`, it rains. Set `ans[i] = -1`. Check if the lake `rains[i]` is already full, if so, return empty array. Add the lake to `full_lakes`. Push the lake and it's next rain day to `lakes_to_dry` heap if the lake will rain in future.
- b. If `rains[i] == 0`, it is a dry day. Check if there are any full lakes to dry (`lakes_to_dry` is not empty). If so, extract the lake with the earliest next rain from `lakes_to_dry` using `heapq.heappop`, update the `ans[i]` with that lake and remove the lake from `full_lakes`.
- c. If it's a dry day but there's no full lakes to dry (`lakes_to_dry` is empty) set `ans[i] = 1` as drying an empty lake does not affect anything
- Step 4: Return `ans` array.
Key Insights
- Insight 1: Use a greedy approach to dry the lake that will flood soonest to maximize our chances of avoiding a flood.
- Insight 2: Prioritize drying lakes that will be rained on again in the future. If a lake isn't going to be rained on, drying it early doesn't give us much advantage and might prevent us from handling future conflicts.
- Insight 3: If at any point a lake is full and rains on that lake again before it is dried, then there is a flood and we must return an empty array.
Complexity Analysis
Time Complexity: O(n log n)
Space Complexity: O(n)
Topics
This problem involves: Array, Hash Table, Binary Search, Greedy, Heap (Priority Queue).
Companies
Asked at: blinkit.