Skip to content

Commit 2ea7f88

Browse files
authored
feat: add solutions to lc problem: No.3272 (#4323)
No.3272.Find the Count of Good Integers
1 parent 7a39c6c commit 2ea7f88

File tree

5 files changed

+418
-29
lines changed

5 files changed

+418
-29
lines changed

Diff for: solution/3200-3299/3272.Find the Count of Good Integers/README.md

+146-7
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,25 @@ tags:
9090

9191
<!-- solution:start -->
9292

93-
### 方法一
93+
### 方法一:枚举 + 组合数学
94+
95+
我们可以考虑枚举所有长度为 $n$ 的回文数,判断它们是否是 $k$ 回文数。由于回文数的性质,我们只需要枚举前半部分的数字,然后将其反转拼接到后面即可。
96+
97+
前半部分的数字长度为 $\lfloor \frac{n - 1}{2} \rfloor$,那么前半部分的数字范围是 $[10^{\lfloor \frac{n - 1}{2} \rfloor}, 10^{\lfloor \frac{n - 1}{2} \rfloor + 1})$。我们可以将前半部分的数字拼接到后面,形成一个长度为 $n$ 的回文数。注意到,如果 $n$ 是奇数,则需要将中间的数字做特殊处理。
98+
99+
然后,我们判断该回文数是否是 $k$ 回文数,如果是,则统计该回文数的所有排列组合。为了避免重复,我们可以使用一个集合 $\textit{vis}$ 来存储已经出现过的回文数的每个最小排列。如果该回文数的最小排列已经出现过,则跳过该回文数。否则,我们统计该回文数有多少个不重复的排列组合,添加到答案中。
100+
101+
我们可以使用一个数组 $\textit{cnt}$ 来统计每个数字出现的次数,然后使用组合数学的公式计算排列组合的数量。具体来说,假设数字 $0$ 出现了 $x_0$ 次,数字 $1$ 出现了 $x_1$ 次,...,数字 $9$ 出现了 $x_9$ 次,那么该回文数的排列组合数量为:
102+
103+
$$
104+
\frac{(n - x_0) \cdot (n - 1)!}{x_0! \cdot x_1! \cdots x_9!}
105+
$$
106+
107+
其中 $(n - x_0)$ 表示最高位可以选择除 $0$ 以外的所有数字,而 $(n - 1)!$ 表示除最高位以外的所有数字的排列组合数量,然后我们除以每个数字出现的次数的阶乘,避免重复。
108+
109+
最后,我们将所有的排列组合数量相加,得到最终的答案。
110+
111+
时间复杂度 $({10}^m \times n \times \log n)$,空间复杂度 $O({10}^m \times n)$,其中 $m = \lfloor \frac{n - 1}{2} \rfloor$。
94112

95113
<!-- tabs:start -->
96114

@@ -270,6 +288,49 @@ func reverseString(s string) string {
270288
#### TypeScript
271289

272290
```ts
291+
function countGoodIntegers(n: number, k: number): number {
292+
const fac = factorial(n);
293+
let ans = 0;
294+
const vis = new Set<string>();
295+
const base = Math.pow(10, Math.floor((n - 1) / 2));
296+
297+
for (let i = base; i < base * 10; i++) {
298+
let s = `${i}`;
299+
const rev = reverseString(s);
300+
if (n % 2 === 1) {
301+
s += rev.substring(1);
302+
} else {
303+
s += rev;
304+
}
305+
306+
if (+s % k !== 0) {
307+
continue;
308+
}
309+
310+
const bs = Array.from(s).sort();
311+
const t = bs.join('');
312+
313+
if (vis.has(t)) {
314+
continue;
315+
}
316+
317+
vis.add(t);
318+
319+
const cnt = Array(10).fill(0);
320+
for (const c of t) {
321+
cnt[+c]++;
322+
}
323+
324+
let res = (n - cnt[0]) * fac[n - 1];
325+
for (const x of cnt) {
326+
res /= fac[x];
327+
}
328+
ans += res;
329+
}
330+
331+
return ans;
332+
}
333+
273334
function factorial(n: number): number[] {
274335
const fac = Array(n + 1).fill(1);
275336
for (let i = 1; i <= n; i++) {
@@ -281,24 +342,90 @@ function factorial(n: number): number[] {
281342
function reverseString(s: string): string {
282343
return s.split('').reverse().join('');
283344
}
345+
```
284346

285-
function countGoodIntegers(n: number, k: number): number {
347+
#### Rust
348+
349+
```rust
350+
impl Solution {
351+
pub fn count_good_integers(n: i32, k: i32) -> i64 {
352+
use std::collections::HashSet;
353+
let n = n as usize;
354+
let k = k as i64;
355+
let mut fac = vec![1_i64; n + 1];
356+
for i in 1..=n {
357+
fac[i] = fac[i - 1] * i as i64;
358+
}
359+
360+
let mut ans = 0;
361+
let mut vis = HashSet::new();
362+
let base = 10_i64.pow(((n - 1) / 2) as u32);
363+
364+
for i in base..base * 10 {
365+
let s = i.to_string();
366+
let rev: String = s.chars().rev().collect();
367+
let full_s = if n % 2 == 0 {
368+
format!("{}{}", s, rev)
369+
} else {
370+
format!("{}{}", s, &rev[1..])
371+
};
372+
373+
let num: i64 = full_s.parse().unwrap();
374+
if num % k != 0 {
375+
continue;
376+
}
377+
378+
let mut arr: Vec<char> = full_s.chars().collect();
379+
arr.sort_unstable();
380+
let t: String = arr.iter().collect();
381+
if vis.contains(&t) {
382+
continue;
383+
}
384+
vis.insert(t);
385+
386+
let mut cnt = vec![0; 10];
387+
for c in arr {
388+
cnt[c as usize - '0' as usize] += 1;
389+
}
390+
391+
let mut res = (n - cnt[0]) as i64 * fac[n - 1];
392+
for &x in &cnt {
393+
if x > 0 {
394+
res /= fac[x];
395+
}
396+
}
397+
ans += res;
398+
}
399+
400+
ans
401+
}
402+
}
403+
```
404+
405+
#### JavaScript
406+
407+
```js
408+
/**
409+
* @param {number} n
410+
* @param {number} k
411+
* @return {number}
412+
*/
413+
var countGoodIntegers = function (n, k) {
286414
const fac = factorial(n);
287415
let ans = 0;
288-
const vis = new Set<string>();
416+
const vis = new Set();
289417
const base = Math.pow(10, Math.floor((n - 1) / 2));
290418

291419
for (let i = base; i < base * 10; i++) {
292-
let s = i.toString();
420+
let s = String(i);
293421
const rev = reverseString(s);
294422
if (n % 2 === 1) {
295423
s += rev.substring(1);
296424
} else {
297425
s += rev;
298426
}
299427

300-
const num = parseInt(s, 10);
301-
if (num % k !== 0) {
428+
if (parseInt(s, 10) % k !== 0) {
302429
continue;
303430
}
304431

@@ -313,7 +440,7 @@ function countGoodIntegers(n: number, k: number): number {
313440

314441
const cnt = Array(10).fill(0);
315442
for (const c of t) {
316-
cnt[+c]++;
443+
cnt[parseInt(c, 10)]++;
317444
}
318445

319446
let res = (n - cnt[0]) * fac[n - 1];
@@ -324,6 +451,18 @@ function countGoodIntegers(n: number, k: number): number {
324451
}
325452

326453
return ans;
454+
};
455+
456+
function factorial(n) {
457+
const fac = Array(n + 1).fill(1);
458+
for (let i = 1; i <= n; i++) {
459+
fac[i] = fac[i - 1] * i;
460+
}
461+
return fac;
462+
}
463+
464+
function reverseString(s) {
465+
return s.split('').reverse().join('');
327466
}
328467
```
329468

0 commit comments

Comments
 (0)