1415-长度为 n 的开心字符串中字典序第 k 小的字符串
一个 「开心字符串」定义为:
- 仅包含小写字母
['a', 'b', 'c']
. - 对所有在
1
到s.length - 1
之间的i
,满足s[i] != s[i + 1]
(字符串的下标从 1 开始)。
比方说,字符串 **” abc”**, “ ac”,”b” 和 “ abcbabcbcb” 都是开心字符串,但是 **” aa”**,
“ baa” 和 “ ababbc” 都不是开心字符串。
给你两个整数 n
和 k
,你需要将长度为 n
的所有开心字符串按字典序排序。
请你返回排序后的第 k 个开心字符串,如果长度为 n
的开心字符串少于 k
个,那么请你返回 空字符串 。
示例 1:
**输入:** n = 1, k = 3
**输出:** "c"
**解释:** 列表 ["a", "b", "c"] 包含了所有长度为 1 的开心字符串。按照字典序排序后第三个字符串为 "c" 。
示例 2:
**输入:** n = 1, k = 4
**输出:** ""
**解释:** 长度为 1 的开心字符串只有 3 个。
示例 3:
**输入:** n = 3, k = 9
**输出:** "cab"
**解释:** 长度为 3 的开心字符串总共有 12 个 ["aba", "abc", "aca", "acb", "bab", "bac", "bca", "bcb", "cab", "cac", "cba", "cbc"] 。第 9 个字符串为 "cab"
示例 4:
**输入:** n = 2, k = 7
**输出:** ""
示例 5:
**输入:** n = 10, k = 100
**输出:** "abacbabacb"
提示:
1 <= n <= 10
1 <= k <= 100
Problem: 1415. 长度为 n 的开心字符串中字典序第 k 小的字符串
[TOC]
思路
先从暴力入手,再来优化
解题方法
步骤一: 首先我们可以看出第一个字母是三种可能a
、b
、c
这三种可能,然后第二个字母分析如下:
- 如果第一个字母是
a
,则,第二个字母有两种可能b
、c
; - 如果第一个字母是
b
,则,第二个字母有两种可能a
、c
; - 如果第一个字母是
c
,则,第二个字母有两种可能a
、b
;
步骤二: 依此类推,第三个字母对应的第二个字母都有两种情况,因此,如果长度为n
的字符串,那么总的数量可能为3\times 2^{n-1种可能。所以可以根据这个式子来判断k
是否超过了:
- 如果k>3\times 2^{n-1,则返回空字符串;
- 如果k\leq 3\times 2^{n-1,则说明存在;
步骤三: 接着可以分析出来字符串中第一个字母分别是a
、b
、c
的数量其实是相等的,即2^{n-1种,因此我们可以根据k
来判断返回的字符串res
的第一个字符是a
还是b
还是c
:
- 如果(k-1)/ 2^{n-1}==0,则说明第一个字符是
a
; - 如果(k-1)/ 2^{n-1}==1,则说明第一个字符是
b
; - 如果(k-1)/ 2^{n-1}==2,则说明第一个字符是
c
;
步骤四: 然后在确定第一个字符之后,k
变为了k=(k-1)mod 2^{n-1,我们可以知道以后的每个字符都是有且只有两种情况,因为不能和上一个字符相同,所以每个分支的总可能性为2^{n-2种可能。我们需要通过k
来判断是属于前一个分支还是后一个分支。例如假设前一个字符为b
,则下一个字符只有a
、c
两种可能,而a
一定是排在c
的前面,所以:
- 如果k/ 2^{n-2}==0,则说明下一个字符是
a
; - 如果k/ 2^{n-2}==1,则说明下一个字符是
c
;
步骤五: 最后一直重复步骤四,直到分支的可能性为1,即s^{n-i}==1,就是所有的字符串全部算出来了。
复杂度
时间复杂度:
O(log(n))
空间复杂度:
O(1)
Code
1 |
|