@@ -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 \t imes 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