comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
Medium |
|
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:
1 <= road.length <= 105
1 <= budget <= 105 + 1
road
consists only of characters'.'
and'x'
.
First, we count the number of each continuous pothole, recorded in the array
Since we want to repair as many potholes as possible, and for a continuous pothole of length
Therefore, we start repairing from the longest pothole. For a pothole of length
The time complexity is
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):
if cnt[k] == 0:
continue
t = min(budget // (k + 1), cnt[k])
ans += t * k
budget -= t * (k + 1)
if budget == 0:
break
cnt[k - 1] += cnt[k] - t
return ans
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 && budget > 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;
}
}
class Solution {
public:
int maxPotholes(string road, int budget) {
road.push_back('.');
int n = road.size();
vector<int> 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 && budget; --k) {
int t = min(budget / (k + 1), cnt[k]);
ans += t * k;
budget -= t * (k + 1);
cnt[k - 1] += cnt[k] - t;
}
return ans;
}
};
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 && budget > 0; k-- {
t := min(budget/(k+1), cnt[k])
ans += t * k
budget -= t * (k + 1)
cnt[k-1] += cnt[k] - t
}
return
}
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 && budget; --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;
}
impl Solution {
pub fn max_potholes(road: String, budget: i32) -> i32 {
let mut cs: Vec<char> = road.chars().collect();
cs.push('.');
let n = cs.len();
let mut cnt: Vec<i32> = vec![0; n];
let mut k = 0;
for c in cs.iter() {
if *c == 'x' {
k += 1;
} else if k > 0 {
cnt[k] += 1;
k = 0;
}
}
let mut ans = 0;
let mut budget = budget;
for k in (1..n).rev() {
if budget == 0 {
break;
}
let t = std::cmp::min(budget / ((k as i32) + 1), cnt[k]);
ans += t * (k as i32);
budget -= t * ((k as i32) + 1);
cnt[k - 1] += cnt[k] - t;
}
ans
}
}
public class Solution {
public int MaxPotholes(string road, int budget) {
road += '.';
int n = road.Length;
int[] cnt = new int[n];
int k = 0;
foreach (char c in road) {
if (c == 'x') {
++k;
} else if (k > 0) {
++cnt[k];
k = 0;
}
}
int ans = 0;
for (k = n - 1; k > 0 && budget > 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;
}
}