Skip to content

Commit e2b21d8

Browse files
authoredMar 18, 2024
feat: add solutions to lc problem: No.3081 (doocs#2457)
No.3081.Replace Question Marks in String to Minimize Its Value
1 parent bef626f commit e2b21d8

File tree

6 files changed

+392
-10
lines changed

6 files changed

+392
-10
lines changed
 

‎solution/3000-3099/3081.Replace Question Marks in String to Minimize Its Value/README.md

+133-5
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,152 @@
7272

7373
## 解法
7474

75-
### 方法一
75+
### 方法一:贪心 + 优先队列
76+
77+
根据题目,我们可以发现,如果一个字母 $c$ 出现的次数为 $v$,那么它对答案贡献的分数为 $1 + 2 + \cdots + (v - 1) = \frac{v \times (v - 1)}{2}$。为了使得答案尽可能小,我们应该尽量替换问号为那些出现次数较少的字母。
78+
79+
因此,我们可以使用优先队列(小根堆)来维护每个字母的出现次数,每次取出出现次数最少的字母,将其记录到数组 $t$ 中,然后将其出现次数加一,再放回优先队列中。最后,我们将数组 $t$ 排序,然后遍历字符串 $s$,将每个问号依次替换为数组 $t$ 中的字母即可。
80+
81+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
7682

7783
<!-- tabs:start -->
7884

7985
```python
80-
86+
class Solution:
87+
def minimizeStringValue(self, s: str) -> str:
88+
cnt = Counter(s)
89+
pq = [(cnt[c], c) for c in ascii_lowercase]
90+
heapify(pq)
91+
t = []
92+
for _ in range(s.count("?")):
93+
v, c = pq[0]
94+
t.append(c)
95+
heapreplace(pq, (v + 1, c))
96+
t.sort()
97+
cs = list(s)
98+
j = 0
99+
for i, c in enumerate(s):
100+
if c == "?":
101+
cs[i] = t[j]
102+
j += 1
103+
return "".join(cs)
81104
```
82105

83106
```java
84-
107+
class Solution {
108+
public String minimizeStringValue(String s) {
109+
int[] cnt = new int[26];
110+
int n = s.length();
111+
int k = 0;
112+
char[] cs = s.toCharArray();
113+
for (char c : cs) {
114+
if (c == '?') {
115+
++k;
116+
} else {
117+
++cnt[c - 'a'];
118+
}
119+
}
120+
PriorityQueue<int[]> pq
121+
= new PriorityQueue<>((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
122+
for (int i = 0; i < 26; ++i) {
123+
pq.offer(new int[] {cnt[i], i});
124+
}
125+
int[] t = new int[k];
126+
for (int j = 0; j < k; ++j) {
127+
int[] p = pq.poll();
128+
t[j] = p[1];
129+
pq.offer(new int[] {p[0] + 1, p[1]});
130+
}
131+
Arrays.sort(t);
132+
133+
for (int i = 0, j = 0; i < n; ++i) {
134+
if (cs[i] == '?') {
135+
cs[i] = (char) (t[j++] + 'a');
136+
}
137+
}
138+
return new String(cs);
139+
}
140+
}
85141
```
86142

87143
```cpp
88-
144+
class Solution {
145+
public:
146+
string minimizeStringValue(string s) {
147+
int cnt[26]{};
148+
int k = 0;
149+
for (char& c : s) {
150+
if (c == '?') {
151+
++k;
152+
} else {
153+
++cnt[c - 'a'];
154+
}
155+
}
156+
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
157+
for (int i = 0; i < 26; ++i) {
158+
pq.push({cnt[i], i});
159+
}
160+
vector<int> t(k);
161+
for (int i = 0; i < k; ++i) {
162+
auto [v, c] = pq.top();
163+
pq.pop();
164+
t[i] = c;
165+
pq.push({v + 1, c});
166+
}
167+
sort(t.begin(), t.end());
168+
int j = 0;
169+
for (char& c : s) {
170+
if (c == '?') {
171+
c = t[j++] + 'a';
172+
}
173+
}
174+
return s;
175+
}
176+
};
89177
```
90178
91179
```go
92-
180+
func minimizeStringValue(s string) string {
181+
cnt := [26]int{}
182+
k := 0
183+
for _, c := range s {
184+
if c == '?' {
185+
k++
186+
} else {
187+
cnt[c-'a']++
188+
}
189+
}
190+
pq := hp{}
191+
for i, c := range cnt {
192+
heap.Push(&pq, pair{c, i})
193+
}
194+
t := make([]int, k)
195+
for i := 0; i < k; i++ {
196+
p := heap.Pop(&pq).(pair)
197+
t[i] = p.c
198+
p.v++
199+
heap.Push(&pq, p)
200+
}
201+
sort.Ints(t)
202+
cs := []byte(s)
203+
j := 0
204+
for i, c := range cs {
205+
if c == '?' {
206+
cs[i] = byte(t[j] + 'a')
207+
j++
208+
}
209+
}
210+
return string(cs)
211+
}
212+
213+
type pair struct{ v, c int }
214+
type hp []pair
215+
216+
func (h hp) Len() int { return len(h) }
217+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v || h[i].v == h[j].v && h[i].c < h[j].c }
218+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
219+
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
220+
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
93221
```
94222

95223
<!-- tabs:end -->

‎solution/3000-3099/3081.Replace Question Marks in String to Minimize Its Value/README_EN.md

+133-5
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,152 @@
6868

6969
## Solutions
7070

71-
### Solution 1
71+
### Solution 1: Greedy + Priority Queue
72+
73+
According to the problem, we can find that if a letter $c$ appears $v$ times, then the score it contributes to the answer is $1 + 2 + \cdots + (v - 1) = \frac{v \times (v - 1)}{2}$. To make the answer as small as possible, we should replace the question marks with those letters that appear less frequently.
74+
75+
Therefore, we can use a priority queue to maintain the occurrence times of each letter, take out the letter with the least occurrence times each time, record it in the array $t$, then increase its occurrence times by one, and put it back into the priority queue. Finally, we sort the array $t$, and then traverse the string $s$, replacing each question mark with the letters in the array $t$ in turn.
76+
77+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the string $s$.
7278

7379
<!-- tabs:start -->
7480

7581
```python
76-
82+
class Solution:
83+
def minimizeStringValue(self, s: str) -> str:
84+
cnt = Counter(s)
85+
pq = [(cnt[c], c) for c in ascii_lowercase]
86+
heapify(pq)
87+
t = []
88+
for _ in range(s.count("?")):
89+
v, c = pq[0]
90+
t.append(c)
91+
heapreplace(pq, (v + 1, c))
92+
t.sort()
93+
cs = list(s)
94+
j = 0
95+
for i, c in enumerate(s):
96+
if c == "?":
97+
cs[i] = t[j]
98+
j += 1
99+
return "".join(cs)
77100
```
78101

79102
```java
80-
103+
class Solution {
104+
public String minimizeStringValue(String s) {
105+
int[] cnt = new int[26];
106+
int n = s.length();
107+
int k = 0;
108+
char[] cs = s.toCharArray();
109+
for (char c : cs) {
110+
if (c == '?') {
111+
++k;
112+
} else {
113+
++cnt[c - 'a'];
114+
}
115+
}
116+
PriorityQueue<int[]> pq
117+
= new PriorityQueue<>((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
118+
for (int i = 0; i < 26; ++i) {
119+
pq.offer(new int[] {cnt[i], i});
120+
}
121+
int[] t = new int[k];
122+
for (int j = 0; j < k; ++j) {
123+
int[] p = pq.poll();
124+
t[j] = p[1];
125+
pq.offer(new int[] {p[0] + 1, p[1]});
126+
}
127+
Arrays.sort(t);
128+
129+
for (int i = 0, j = 0; i < n; ++i) {
130+
if (cs[i] == '?') {
131+
cs[i] = (char) (t[j++] + 'a');
132+
}
133+
}
134+
return new String(cs);
135+
}
136+
}
81137
```
82138

83139
```cpp
84-
140+
class Solution {
141+
public:
142+
string minimizeStringValue(string s) {
143+
int cnt[26]{};
144+
int k = 0;
145+
for (char& c : s) {
146+
if (c == '?') {
147+
++k;
148+
} else {
149+
++cnt[c - 'a'];
150+
}
151+
}
152+
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
153+
for (int i = 0; i < 26; ++i) {
154+
pq.push({cnt[i], i});
155+
}
156+
vector<int> t(k);
157+
for (int i = 0; i < k; ++i) {
158+
auto [v, c] = pq.top();
159+
pq.pop();
160+
t[i] = c;
161+
pq.push({v + 1, c});
162+
}
163+
sort(t.begin(), t.end());
164+
int j = 0;
165+
for (char& c : s) {
166+
if (c == '?') {
167+
c = t[j++] + 'a';
168+
}
169+
}
170+
return s;
171+
}
172+
};
85173
```
86174
87175
```go
88-
176+
func minimizeStringValue(s string) string {
177+
cnt := [26]int{}
178+
k := 0
179+
for _, c := range s {
180+
if c == '?' {
181+
k++
182+
} else {
183+
cnt[c-'a']++
184+
}
185+
}
186+
pq := hp{}
187+
for i, c := range cnt {
188+
heap.Push(&pq, pair{c, i})
189+
}
190+
t := make([]int, k)
191+
for i := 0; i < k; i++ {
192+
p := heap.Pop(&pq).(pair)
193+
t[i] = p.c
194+
p.v++
195+
heap.Push(&pq, p)
196+
}
197+
sort.Ints(t)
198+
cs := []byte(s)
199+
j := 0
200+
for i, c := range cs {
201+
if c == '?' {
202+
cs[i] = byte(t[j] + 'a')
203+
j++
204+
}
205+
}
206+
return string(cs)
207+
}
208+
209+
type pair struct{ v, c int }
210+
type hp []pair
211+
212+
func (h hp) Len() int { return len(h) }
213+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v || h[i].v == h[j].v && h[i].c < h[j].c }
214+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
215+
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
216+
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
89217
```
90218

91219
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public:
3+
string minimizeStringValue(string s) {
4+
int cnt[26]{};
5+
int k = 0;
6+
for (char& c : s) {
7+
if (c == '?') {
8+
++k;
9+
} else {
10+
++cnt[c - 'a'];
11+
}
12+
}
13+
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
14+
for (int i = 0; i < 26; ++i) {
15+
pq.push({cnt[i], i});
16+
}
17+
vector<int> t(k);
18+
for (int i = 0; i < k; ++i) {
19+
auto [v, c] = pq.top();
20+
pq.pop();
21+
t[i] = c;
22+
pq.push({v + 1, c});
23+
}
24+
sort(t.begin(), t.end());
25+
int j = 0;
26+
for (char& c : s) {
27+
if (c == '?') {
28+
c = t[j++] + 'a';
29+
}
30+
}
31+
return s;
32+
}
33+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
func minimizeStringValue(s string) string {
2+
cnt := [26]int{}
3+
k := 0
4+
for _, c := range s {
5+
if c == '?' {
6+
k++
7+
} else {
8+
cnt[c-'a']++
9+
}
10+
}
11+
pq := hp{}
12+
for i, c := range cnt {
13+
heap.Push(&pq, pair{c, i})
14+
}
15+
t := make([]int, k)
16+
for i := 0; i < k; i++ {
17+
p := heap.Pop(&pq).(pair)
18+
t[i] = p.c
19+
p.v++
20+
heap.Push(&pq, p)
21+
}
22+
sort.Ints(t)
23+
cs := []byte(s)
24+
j := 0
25+
for i, c := range cs {
26+
if c == '?' {
27+
cs[i] = byte(t[j] + 'a')
28+
j++
29+
}
30+
}
31+
return string(cs)
32+
}
33+
34+
type pair struct{ v, c int }
35+
type hp []pair
36+
37+
func (h hp) Len() int { return len(h) }
38+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v || h[i].v == h[j].v && h[i].c < h[j].c }
39+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
40+
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
41+
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

0 commit comments

Comments
 (0)
Please sign in to comment.