Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2ea7f88

Browse files
feat: add solutions to lc problem: No.3272 (doocs#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

‎solution/3200-3299/3272.Find the Count of Good Integers/README.md‎

Lines changed: 146 additions & 7 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /