Skip to content

Commit 800543d

Browse files
authored
feat: add solutions for lc No.1415 (#5063)
1 parent 1c3980f commit 800543d

13 files changed

Lines changed: 826 additions & 8 deletions

File tree

solution/1400-1499/1415.The k-th Lexicographical String of All Happy Strings of Length n/README.md

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,245 @@ public class Solution {
350350
351351
<!-- solution:end -->
352352
353+
<!-- solution:start -->
354+
355+
### 方法二:数学
356+
357+
我们可以直接计算出第 $k$ 个开心字符串是什么,而不需要生成所有的开心字符串。
358+
359+
从长度为 $n$ 的开心字符串的第一个字符串开始,我们可以计算出每个字符的位置应该是什么。
360+
361+
对于长度为 $n$ 的开心字符串,第一个字符有 $3$ 种选择,第二个字符有 $2$ 种选择(不能和第一个字符相同),第三个字符也有 $2$ 种选择(不能和第二个字符相同),以此类推,直到第 $n$ 个字符也有 $2$ 种选择(不能和第 $n-1$ 个字符相同)。因此,长度为 $n$ 的开心字符串的总数为 $3 \times 2^{n-1}$。
362+
363+
如果 $k$ 大于长度为 $n$ 的开心字符串的总数,那么我们直接返回空字符串。
364+
365+
否则,我们从第一个字符开始,依次计算每个字符的位置应该是什么。对于第 $i$ 个字符,我们枚举字符集 $\{a, b, c\}$,如果当前字符串的最后一个字符不等于 $c$,则计算出剩余的开心字符串的总数,如果 $k$ 小于等于剩余的开心字符串的总数,那么我们就将字符 $c$ 加入当前字符串,然后继续计算下一个字符的位置;否则,我们就将 $k$ 减去剩余的开心字符串的总数,然后继续枚举下一个字符。
366+
367+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串长度。
368+
369+
<!-- tabs:start -->
370+
371+
#### Python3
372+
373+
```python
374+
class Solution:
375+
def getHappyString(self, n: int, k: int) -> str:
376+
if k > 3 * (1 << (n - 1)):
377+
return ""
378+
cs = "abc"
379+
ans = []
380+
for i in range(n):
381+
remain = 1 << (n - i - 1)
382+
for c in cs:
383+
if ans and ans[-1] == c:
384+
continue
385+
if k <= remain:
386+
ans.append(c)
387+
break
388+
k -= remain
389+
return "".join(ans)
390+
```
391+
392+
#### Java
393+
394+
```java
395+
class Solution {
396+
public String getHappyString(int n, int k) {
397+
if (k > 3 * (1 << (n - 1))) {
398+
return "";
399+
}
400+
String cs = "abc";
401+
StringBuilder ans = new StringBuilder();
402+
for (int i = 0; i < n; i++) {
403+
int remain = 1 << (n - i - 1);
404+
for (char c : cs.toCharArray()) {
405+
if (ans.length() > 0 && ans.charAt(ans.length() - 1) == c) {
406+
continue;
407+
}
408+
if (k <= remain) {
409+
ans.append(c);
410+
break;
411+
}
412+
k -= remain;
413+
}
414+
}
415+
return ans.toString();
416+
}
417+
}
418+
```
419+
420+
#### C++
421+
422+
```cpp
423+
class Solution {
424+
public:
425+
string getHappyString(int n, int k) {
426+
if (k > 3 * (1 << (n - 1))) {
427+
return "";
428+
}
429+
string cs = "abc";
430+
string ans;
431+
for (int i = 0; i < n; ++i) {
432+
int remain = 1 << (n - i - 1);
433+
for (char c : cs) {
434+
if (!ans.empty() && ans.back() == c) {
435+
continue;
436+
}
437+
if (k <= remain) {
438+
ans.push_back(c);
439+
break;
440+
}
441+
k -= remain;
442+
}
443+
}
444+
return ans;
445+
}
446+
};
447+
```
448+
449+
#### Go
450+
451+
```go
452+
func getHappyString(n int, k int) string {
453+
if k > 3*(1<<(n-1)) {
454+
return ""
455+
}
456+
cs := "abc"
457+
ans := make([]byte, 0, n)
458+
for i := 0; i < n; i++ {
459+
remain := 1 << (n - i - 1)
460+
for j := 0; j < len(cs); j++ {
461+
c := cs[j]
462+
if len(ans) > 0 && ans[len(ans)-1] == c {
463+
continue
464+
}
465+
if k <= remain {
466+
ans = append(ans, c)
467+
break
468+
}
469+
k -= remain
470+
}
471+
}
472+
return string(ans)
473+
}
474+
```
475+
476+
#### TypeScript
477+
478+
```ts
479+
function getHappyString(n: number, k: number): string {
480+
if (k > 3 * (1 << (n - 1))) {
481+
return '';
482+
}
483+
const cs = 'abc';
484+
const ans: string[] = [];
485+
for (let i = 0; i < n; i++) {
486+
const remain = 1 << (n - i - 1);
487+
for (const c of cs) {
488+
if (ans.at(-1) === c) {
489+
continue;
490+
}
491+
if (k <= remain) {
492+
ans.push(c);
493+
break;
494+
}
495+
k -= remain;
496+
}
497+
}
498+
return ans.join('');
499+
}
500+
```
501+
502+
#### Rust
503+
504+
```rust
505+
impl Solution {
506+
pub fn get_happy_string(n: i32, mut k: i32) -> String {
507+
if k > 3 * (1 << (n - 1)) {
508+
return String::new();
509+
}
510+
let cs = ['a', 'b', 'c'];
511+
let mut ans: Vec<char> = Vec::with_capacity(n as usize);
512+
for i in 0..n {
513+
let remain = 1 << (n - i - 1);
514+
for &c in &cs {
515+
if !ans.is_empty() && *ans.last().unwrap() == c {
516+
continue;
517+
}
518+
if k <= remain {
519+
ans.push(c);
520+
break;
521+
}
522+
k -= remain;
523+
}
524+
}
525+
ans.into_iter().collect()
526+
}
527+
}
528+
```
529+
530+
#### JavaScript
531+
532+
```js
533+
/**
534+
* @param {number} n
535+
* @param {number} k
536+
* @return {string}
537+
*/
538+
var getHappyString = function (n, k) {
539+
if (k > 3 * (1 << (n - 1))) {
540+
return '';
541+
}
542+
const cs = 'abc';
543+
const ans = [];
544+
for (let i = 0; i < n; i++) {
545+
const remain = 1 << (n - i - 1);
546+
for (let j = 0; j < cs.length; j++) {
547+
const c = cs[j];
548+
if (ans.at(-1) === c) {
549+
continue;
550+
}
551+
if (k <= remain) {
552+
ans.push(c);
553+
break;
554+
}
555+
k -= remain;
556+
}
557+
}
558+
return ans.join('');
559+
};
560+
```
561+
562+
#### C#
563+
564+
```cs
565+
public class Solution {
566+
public string GetHappyString(int n, int k) {
567+
if (k > 3 * (1 << (n - 1))) {
568+
return "";
569+
}
570+
string cs = "abc";
571+
var ans = new System.Text.StringBuilder();
572+
for (int i = 0; i < n; i++) {
573+
int remain = 1 << (n - i - 1);
574+
foreach (char c in cs) {
575+
if (ans.Length > 0 && ans[ans.Length - 1] == c) {
576+
continue;
577+
}
578+
if (k <= remain) {
579+
ans.Append(c);
580+
break;
581+
}
582+
k -= remain;
583+
}
584+
}
585+
return ans.ToString();
586+
}
587+
}
588+
```
589+
590+
<!-- tabs:end -->
591+
592+
<!-- solution:end -->
593+
353594
<!-- problem:end -->

0 commit comments

Comments
 (0)