diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md new file mode 100644 index 0000000000000..b148617c6d56f --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md @@ -0,0 +1,205 @@ +# [3119. Maximum Number of Potholes That Can Be Fixed](https://leetcode.cn/problems/maximum-number-of-potholes-that-can-be-fixed) + +[English Version](/solution/3100-3199/3119.Maximum%20Number%20of%20Potholes%20That%20Can%20Be%20Fixed/README_EN.md) + + + +## 题目描述 + + + +

You are given a string road, consisting only of characters "x" and ".", where each "x" denotes a pothole and each "." denotes a smooth road, and an integer budget.

+ +

In one repair operation, you can repair n consecutive potholes for a price of n + 1.

+ +

Return the maximum number of potholes that can be fixed such that the sum of the prices of all of the fixes doesn't go over the given budget.

+ +

 

+

Example 1:

+ +
+

Input: road = "..", budget = 5

+ +

Output: 0

+ +

Explanation:

+ +

There are no potholes to be fixed.

+
+ +

Example 2:

+ +
+

Input: road = "..xxxxx", budget = 4

+ +

Output: 3

+ +

Explanation:

+ +

We fix the first three potholes (they are consecutive). The budget needed for this task is 3 + 1 = 4.

+
+ +

Example 3:

+ +
+

Input: road = "x.x.xxx...x", budget = 14

+ +

Output: 6

+ +

Explanation:

+ +

We can fix all the potholes. The total cost would be (1 + 1) + (1 + 1) + (3 + 1) + (1 + 1) = 10 which is within our budget of 14.

+
+ +

 

+

Constraints:

+ + + +## 解法 + +### 方法一:计数 + 贪心 + +我们首先统计出每个连续的坑洼的数量,记录在数组 $cnt$ 中,即 $cnt[k]$ 表示有 $cnt[k]$ 个长度为 $k$ 的连续坑洼。 + +由于我们要尽可能多地修补坑洼,而对于长度为 $k$ 的连续坑洼,我们需要花费 $k + 1$ 的代价,应该优先修补长度较长的坑洼,这样可以使得代价最小。 + +因此,我们从最长的坑洼开始修补,对于长度为 $k$ 的坑洼,我们最多可以修补的个数为 $t = \min(\text{budget} / (k + 1), \text{cnt}[k])$,我们将修补的个数乘以长度 $k$ 加到答案中,然后更新剩余的预算。对于长度为 $k$ 的其余 $cnt[k] - t$ 个坑洼,我们将它们合并到长度为 $k - 1$ 的坑洼中。继续这个过程,直到遍历完所有的坑洼。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $road$ 的长度。 + + + +```python +class Solution: + def maxPotholes(self, road: str, budget: int) -> int: + road += "." + n = len(road) + cnt = [0] * n + k = 0 + for c in road: + if c == "x": + k += 1 + elif k: + cnt[k] += 1 + k = 0 + ans = 0 + for k in range(n - 1, 0, -1): + t = min(budget // (k + 1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k - 1] += cnt[k] - t + return ans +``` + +```java +class Solution { + public int maxPotholes(String road, int budget) { + road += "."; + int n = road.length(); + int[] cnt = new int[n]; + int k = 0; + for (char c : road.toCharArray()) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0; --k) { + int t = Math.min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} +``` + +```cpp +class Solution { +public: + int maxPotholes(string road, int budget) { + road.push_back('.'); + int n = road.size(); + vector cnt(n); + int k = 0; + for (char& c : road) { + if (c == 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k; --k) { + int t = min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +}; +``` + +```go +func maxPotholes(road string, budget int) (ans int) { + road += "." + n := len(road) + cnt := make([]int, n) + k := 0 + for _, c := range road { + if c == 'x' { + k++ + } else if k > 0 { + cnt[k]++ + k = 0 + } + } + for k = n - 1; k > 0; k-- { + t := min(budget/(k+1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k-1] += cnt[k] - t + } + return +} +``` + +```ts +function maxPotholes(road: string, budget: number): number { + road += '.'; + const n = road.length; + const cnt: number[] = Array(n).fill(0); + let k = 0; + for (const c of road) { + if (c === 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + let ans = 0; + for (k = n - 1; k; --k) { + const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; +} +``` + + + + diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md new file mode 100644 index 0000000000000..3541275708ea2 --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md @@ -0,0 +1,203 @@ +# [3119. Maximum Number of Potholes That Can Be Fixed](https://leetcode.com/problems/maximum-number-of-potholes-that-can-be-fixed) + +[中文文档](/solution/3100-3199/3119.Maximum%20Number%20of%20Potholes%20That%20Can%20Be%20Fixed/README.md) + + + +## Description + +

You are given a string road, consisting only of characters "x" and ".", where each "x" denotes a pothole and each "." denotes a smooth road, and an integer budget.

+ +

In one repair operation, you can repair n consecutive potholes for a price of n + 1.

+ +

Return the maximum number of potholes that can be fixed such that the sum of the prices of all of the fixes doesn't go over the given budget.

+ +

 

+

Example 1:

+ +
+

Input: road = "..", budget = 5

+ +

Output: 0

+ +

Explanation:

+ +

There are no potholes to be fixed.

+
+ +

Example 2:

+ +
+

Input: road = "..xxxxx", budget = 4

+ +

Output: 3

+ +

Explanation:

+ +

We fix the first three potholes (they are consecutive). The budget needed for this task is 3 + 1 = 4.

+
+ +

Example 3:

+ +
+

Input: road = "x.x.xxx...x", budget = 14

+ +

Output: 6

+ +

Explanation:

+ +

We can fix all the potholes. The total cost would be (1 + 1) + (1 + 1) + (3 + 1) + (1 + 1) = 10 which is within our budget of 14.

+
+ +

 

+

Constraints:

+ + + +## Solutions + +### Solution 1: Counting + Greedy + +First, we count the number of each continuous pothole, recorded in the array $cnt$, i.e., $cnt[k]$ represents there are $cnt[k]$ continuous potholes of length $k$. + +Since we want to repair as many potholes as possible, and for a continuous pothole of length $k$, we need to spend a cost of $k + 1$, we should prioritize repairing longer potholes to minimize the cost. + +Therefore, we start repairing from the longest pothole. For a pothole of length $k$, the maximum number we can repair is $t = \min(\text{budget} / (k + 1), \text{cnt}[k])$. We add the number of repairs multiplied by the length $k$ to the answer, then update the remaining budget. For the remaining $cnt[k] - t$ potholes of length $k$, we merge them into the potholes of length $k - 1$. Continue this process until all potholes are traversed. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string $road$. + + + +```python +class Solution: + def maxPotholes(self, road: str, budget: int) -> int: + road += "." + n = len(road) + cnt = [0] * n + k = 0 + for c in road: + if c == "x": + k += 1 + elif k: + cnt[k] += 1 + k = 0 + ans = 0 + for k in range(n - 1, 0, -1): + t = min(budget // (k + 1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k - 1] += cnt[k] - t + return ans +``` + +```java +class Solution { + public int maxPotholes(String road, int budget) { + road += "."; + int n = road.length(); + int[] cnt = new int[n]; + int k = 0; + for (char c : road.toCharArray()) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0; --k) { + int t = Math.min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} +``` + +```cpp +class Solution { +public: + int maxPotholes(string road, int budget) { + road.push_back('.'); + int n = road.size(); + vector cnt(n); + int k = 0; + for (char& c : road) { + if (c == 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k; --k) { + int t = min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +}; +``` + +```go +func maxPotholes(road string, budget int) (ans int) { + road += "." + n := len(road) + cnt := make([]int, n) + k := 0 + for _, c := range road { + if c == 'x' { + k++ + } else if k > 0 { + cnt[k]++ + k = 0 + } + } + for k = n - 1; k > 0; k-- { + t := min(budget/(k+1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k-1] += cnt[k] - t + } + return +} +``` + +```ts +function maxPotholes(road: string, budget: number): number { + road += '.'; + const n = road.length; + const cnt: number[] = Array(n).fill(0); + let k = 0; + for (const c of road) { + if (c === 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + let ans = 0; + for (k = n - 1; k; --k) { + const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; +} +``` + + + + diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp new file mode 100644 index 0000000000000..d7e0d2dba6f2e --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp @@ -0,0 +1,25 @@ +class Solution { +public: + int maxPotholes(string road, int budget) { + road.push_back('.'); + int n = road.size(); + vector cnt(n); + int k = 0; + for (char& c : road) { + if (c == 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k; --k) { + int t = min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go new file mode 100644 index 0000000000000..252c6fdd8df4f --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go @@ -0,0 +1,21 @@ +func maxPotholes(road string, budget int) (ans int) { + road += "." + n := len(road) + cnt := make([]int, n) + k := 0 + for _, c := range road { + if c == 'x' { + k++ + } else if k > 0 { + cnt[k]++ + k = 0 + } + } + for k = n - 1; k > 0; k-- { + t := min(budget/(k+1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k-1] += cnt[k] - t + } + return +} \ No newline at end of file diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java new file mode 100644 index 0000000000000..83b83144db179 --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java @@ -0,0 +1,24 @@ +class Solution { + public int maxPotholes(String road, int budget) { + road += "."; + int n = road.length(); + int[] cnt = new int[n]; + int k = 0; + for (char c : road.toCharArray()) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0; --k) { + int t = Math.min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py new file mode 100644 index 0000000000000..ee8f4d510521f --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py @@ -0,0 +1,19 @@ +class Solution: + def maxPotholes(self, road: str, budget: int) -> int: + road += "." + n = len(road) + cnt = [0] * n + k = 0 + for c in road: + if c == "x": + k += 1 + elif k: + cnt[k] += 1 + k = 0 + ans = 0 + for k in range(n - 1, 0, -1): + t = min(budget // (k + 1), cnt[k]) + ans += t * k + budget -= t * (k + 1) + cnt[k - 1] += cnt[k] - t + return ans diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts new file mode 100644 index 0000000000000..0d64e6ad69557 --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts @@ -0,0 +1,22 @@ +function maxPotholes(road: string, budget: number): number { + road += '.'; + const n = road.length; + const cnt: number[] = Array(n).fill(0); + let k = 0; + for (const c of road) { + if (c === 'x') { + ++k; + } else if (k) { + ++cnt[k]; + k = 0; + } + } + let ans = 0; + for (k = n - 1; k; --k) { + const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; +} diff --git a/solution/README.md b/solution/README.md index bce601073a66b..2e7649ab30cd3 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3129,6 +3129,7 @@ | 3116 | [单面值组合的第 K 小金额](/solution/3100-3199/3116.Kth%20Smallest%20Amount%20With%20Single%20Denomination%20Combination/README.md) | | 困难 | 第 393 场周赛 | | 3117 | [划分数组得到最小的值之和](/solution/3100-3199/3117.Minimum%20Sum%20of%20Values%20by%20Dividing%20Array/README.md) | | 困难 | 第 393 场周赛 | | 3118 | [Friday Purchase III](/solution/3100-3199/3118.Friday%20Purchase%20III/README.md) | | 中等 | 🔒 | +| 3119 | [Maximum Number of Potholes That Can Be Fixed](/solution/3100-3199/3119.Maximum%20Number%20of%20Potholes%20That%20Can%20Be%20Fixed/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 57d9877ee4fdf..aa075870fa9db 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3127,6 +3127,7 @@ Press Control + F(or Command + F on | 3116 | [Kth Smallest Amount With Single Denomination Combination](/solution/3100-3199/3116.Kth%20Smallest%20Amount%20With%20Single%20Denomination%20Combination/README_EN.md) | | Hard | Weekly Contest 393 | | 3117 | [Minimum Sum of Values by Dividing Array](/solution/3100-3199/3117.Minimum%20Sum%20of%20Values%20by%20Dividing%20Array/README_EN.md) | | Hard | Weekly Contest 393 | | 3118 | [Friday Purchase III](/solution/3100-3199/3118.Friday%20Purchase%20III/README_EN.md) | | Medium | 🔒 | +| 3119 | [Maximum Number of Potholes That Can Be Fixed](/solution/3100-3199/3119.Maximum%20Number%20of%20Potholes%20That%20Can%20Be%20Fixed/README_EN.md) | | Medium | 🔒 | ## Copyright