Skip to content

Commit 0e13a6e

Browse files
authored
feat: add solutions to lc problem: No.3517 (doocs#4867)
1 parent 291f917 commit 0e13a6e

File tree

7 files changed

+400
-8
lines changed

7 files changed

+400
-8
lines changed

solution/3500-3599/3517.Smallest Palindromic Rearrangement I/README.md

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,32 +86,165 @@ tags:
8686

8787
<!-- solution:start -->
8888

89-
### 方法一
89+
### 方法一:计数
90+
91+
我们首先统计字符串中每个字符的出现次数,记录在哈希表或数组 $\textit{cnt}$ 中。由于字符串是回文字符串,因此每个字符的出现次数要么是偶数次,要么有且仅有一个字符出现奇数次。
92+
93+
接下来,我们从字典序最小的字符开始,依次将每个字符的一半次数添加到结果字符串的前半部分 $\textit{t}$ 中。如果某个字符出现了奇数次,我们将该字符记录为中间字符 $\textit{ch}$。最后,我们将 $\textit{t}$、$\textit{ch}$ 和 $\textit{t}$ 的反转拼接起来,得到最终的按字典序排列的最小回文排列。
94+
95+
时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(|\Sigma|)$,其中 $|\Sigma|$ 是字符集的大小,本题中 $|\Sigma|=26$。
9096

9197
<!-- tabs:start -->
9298

9399
#### Python3
94100

95101
```python
96-
102+
class Solution:
103+
def smallestPalindrome(self, s: str) -> str:
104+
cnt = Counter(s)
105+
t = []
106+
ch = ""
107+
for c in ascii_lowercase:
108+
v = cnt[c] // 2
109+
t.append(c * v)
110+
cnt[c] -= v * 2
111+
if cnt[c] == 1:
112+
ch = c
113+
ans = "".join(t)
114+
ans = ans + ch + ans[::-1]
115+
return ans
97116
```
98117

99118
#### Java
100119

101120
```java
102-
121+
class Solution {
122+
public String smallestPalindrome(String s) {
123+
int[] cnt = new int[26];
124+
for (char c : s.toCharArray()) {
125+
cnt[c - 'a']++;
126+
}
127+
128+
StringBuilder t = new StringBuilder();
129+
String ch = "";
130+
131+
for (char c = 'a'; c <= 'z'; c++) {
132+
int idx = c - 'a';
133+
int v = cnt[idx] / 2;
134+
if (v > 0) {
135+
t.append(String.valueOf(c).repeat(v));
136+
}
137+
cnt[idx] -= v * 2;
138+
if (cnt[idx] == 1) {
139+
ch = String.valueOf(c);
140+
}
141+
}
142+
143+
String ans = t.toString();
144+
ans = ans + ch + new StringBuilder(ans).reverse();
145+
return ans;
146+
}
147+
}
103148
```
104149

105150
#### C++
106151

107152
```cpp
108-
153+
class Solution {
154+
public:
155+
string smallestPalindrome(string s) {
156+
vector<int> cnt(26);
157+
for (char c : s) {
158+
cnt[c - 'a']++;
159+
}
160+
string t = "";
161+
string ch = "";
162+
for (char c = 'a'; c <= 'z'; ++c) {
163+
int v = cnt[c - 'a'] / 2;
164+
if (v > 0) {
165+
t.append(v, c);
166+
}
167+
cnt[c - 'a'] -= v * 2;
168+
if (cnt[c - 'a'] == 1) {
169+
ch = string(1, c);
170+
}
171+
}
172+
string ans = t;
173+
ans += ch;
174+
string rev = t;
175+
reverse(rev.begin(), rev.end());
176+
ans += rev;
177+
return ans;
178+
}
179+
};
109180
```
110181
111182
#### Go
112183
113184
```go
185+
func smallestPalindrome(s string) string {
186+
cnt := make([]int, 26)
187+
for i := 0; i < len(s); i++ {
188+
cnt[s[i]-'a']++
189+
}
190+
191+
t := make([]byte, 0, len(s)/2)
192+
var ch byte
193+
for c := byte('a'); c <= 'z'; c++ {
194+
v := cnt[c-'a'] / 2
195+
for i := 0; i < v; i++ {
196+
t = append(t, c)
197+
}
198+
cnt[c-'a'] -= v * 2
199+
if cnt[c-'a'] == 1 {
200+
ch = c
201+
}
202+
}
203+
204+
totalLen := len(t) * 2
205+
if ch != 0 {
206+
totalLen++
207+
}
208+
var sb strings.Builder
209+
sb.Grow(totalLen)
210+
211+
sb.Write(t)
212+
if ch != 0 {
213+
sb.WriteByte(ch)
214+
}
215+
for i := len(t) - 1; i >= 0; i-- {
216+
sb.WriteByte(t[i])
217+
}
218+
return sb.String()
219+
}
220+
```
114221

222+
#### TypeScript
223+
224+
```ts
225+
function smallestPalindrome(s: string): string {
226+
const ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz';
227+
const cnt = new Array<number>(26).fill(0);
228+
for (const chKey of s) {
229+
cnt[chKey.charCodeAt(0) - 97]++;
230+
}
231+
232+
const t: string[] = [];
233+
let ch = '';
234+
for (let i = 0; i < 26; i++) {
235+
const c = ascii_lowercase[i];
236+
const v = Math.floor(cnt[i] / 2);
237+
t.push(c.repeat(v));
238+
cnt[i] -= v * 2;
239+
if (cnt[i] === 1) {
240+
ch = c;
241+
}
242+
}
243+
244+
let ans = t.join('');
245+
ans = ans + ch + ans.split('').reverse().join('');
246+
return ans;
247+
}
115248
```
116249

117250
<!-- tabs:end -->

solution/3500-3599/3517.Smallest Palindromic Rearrangement I/README_EN.md

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,32 +76,165 @@ tags:
7676

7777
<!-- solution:start -->
7878

79-
### Solution 1
79+
### Solution 1: Counting
80+
81+
We first count the occurrence of each character in the string and record it in a hash table or array $\textit{cnt}$. Since the string is a palindrome, the count of each character is either even, or there is exactly one character with an odd count.
82+
83+
Next, starting from the lexicographically smallest character, we sequentially add half of each character's count to the first half of the result string $\textit{t}$. If a character appears an odd number of times, we record it as the middle character $\textit{ch}$. Finally, we concatenate $\textit{t}$, $\textit{ch}$, and the reverse of $\textit{t}$ to obtain the final lexicographically smallest palindromic rearrangement.
84+
85+
The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(|\Sigma|)$, where $|\Sigma|$ is the size of the character set, which is $26$ in this problem.
8086

8187
<!-- tabs:start -->
8288

8389
#### Python3
8490

8591
```python
86-
92+
class Solution:
93+
def smallestPalindrome(self, s: str) -> str:
94+
cnt = Counter(s)
95+
t = []
96+
ch = ""
97+
for c in ascii_lowercase:
98+
v = cnt[c] // 2
99+
t.append(c * v)
100+
cnt[c] -= v * 2
101+
if cnt[c] == 1:
102+
ch = c
103+
ans = "".join(t)
104+
ans = ans + ch + ans[::-1]
105+
return ans
87106
```
88107

89108
#### Java
90109

91110
```java
92-
111+
class Solution {
112+
public String smallestPalindrome(String s) {
113+
int[] cnt = new int[26];
114+
for (char c : s.toCharArray()) {
115+
cnt[c - 'a']++;
116+
}
117+
118+
StringBuilder t = new StringBuilder();
119+
String ch = "";
120+
121+
for (char c = 'a'; c <= 'z'; c++) {
122+
int idx = c - 'a';
123+
int v = cnt[idx] / 2;
124+
if (v > 0) {
125+
t.append(String.valueOf(c).repeat(v));
126+
}
127+
cnt[idx] -= v * 2;
128+
if (cnt[idx] == 1) {
129+
ch = String.valueOf(c);
130+
}
131+
}
132+
133+
String ans = t.toString();
134+
ans = ans + ch + new StringBuilder(ans).reverse();
135+
return ans;
136+
}
137+
}
93138
```
94139

95140
#### C++
96141

97142
```cpp
98-
143+
class Solution {
144+
public:
145+
string smallestPalindrome(string s) {
146+
vector<int> cnt(26);
147+
for (char c : s) {
148+
cnt[c - 'a']++;
149+
}
150+
string t = "";
151+
string ch = "";
152+
for (char c = 'a'; c <= 'z'; ++c) {
153+
int v = cnt[c - 'a'] / 2;
154+
if (v > 0) {
155+
t.append(v, c);
156+
}
157+
cnt[c - 'a'] -= v * 2;
158+
if (cnt[c - 'a'] == 1) {
159+
ch = string(1, c);
160+
}
161+
}
162+
string ans = t;
163+
ans += ch;
164+
string rev = t;
165+
reverse(rev.begin(), rev.end());
166+
ans += rev;
167+
return ans;
168+
}
169+
};
99170
```
100171
101172
#### Go
102173
103174
```go
175+
func smallestPalindrome(s string) string {
176+
cnt := make([]int, 26)
177+
for i := 0; i < len(s); i++ {
178+
cnt[s[i]-'a']++
179+
}
180+
181+
t := make([]byte, 0, len(s)/2)
182+
var ch byte
183+
for c := byte('a'); c <= 'z'; c++ {
184+
v := cnt[c-'a'] / 2
185+
for i := 0; i < v; i++ {
186+
t = append(t, c)
187+
}
188+
cnt[c-'a'] -= v * 2
189+
if cnt[c-'a'] == 1 {
190+
ch = c
191+
}
192+
}
193+
194+
totalLen := len(t) * 2
195+
if ch != 0 {
196+
totalLen++
197+
}
198+
var sb strings.Builder
199+
sb.Grow(totalLen)
200+
201+
sb.Write(t)
202+
if ch != 0 {
203+
sb.WriteByte(ch)
204+
}
205+
for i := len(t) - 1; i >= 0; i-- {
206+
sb.WriteByte(t[i])
207+
}
208+
return sb.String()
209+
}
210+
```
104211

212+
#### TypeScript
213+
214+
```ts
215+
function smallestPalindrome(s: string): string {
216+
const ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz';
217+
const cnt = new Array<number>(26).fill(0);
218+
for (const chKey of s) {
219+
cnt[chKey.charCodeAt(0) - 97]++;
220+
}
221+
222+
const t: string[] = [];
223+
let ch = '';
224+
for (let i = 0; i < 26; i++) {
225+
const c = ascii_lowercase[i];
226+
const v = Math.floor(cnt[i] / 2);
227+
t.push(c.repeat(v));
228+
cnt[i] -= v * 2;
229+
if (cnt[i] === 1) {
230+
ch = c;
231+
}
232+
}
233+
234+
let ans = t.join('');
235+
ans = ans + ch + ans.split('').reverse().join('');
236+
return ans;
237+
}
105238
```
106239

107240
<!-- tabs:end -->
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
string smallestPalindrome(string s) {
4+
vector<int> cnt(26);
5+
for (char c : s) {
6+
cnt[c - 'a']++;
7+
}
8+
string t = "";
9+
string ch = "";
10+
for (char c = 'a'; c <= 'z'; ++c) {
11+
int v = cnt[c - 'a'] / 2;
12+
if (v > 0) {
13+
t.append(v, c);
14+
}
15+
cnt[c - 'a'] -= v * 2;
16+
if (cnt[c - 'a'] == 1) {
17+
ch = string(1, c);
18+
}
19+
}
20+
string ans = t;
21+
ans += ch;
22+
string rev = t;
23+
reverse(rev.begin(), rev.end());
24+
ans += rev;
25+
return ans;
26+
}
27+
};

0 commit comments

Comments
 (0)