题目
思路
利用树状结构和分组思想,字符串首位可分三组、后面每一位可分两组,根据k确定第k个字符串所在组数及对应字母。即三颗满二叉树,根节点分别为a、b、c ,一共3*2^(n-1)个叶子节点,寻找第k个叶子节点。
代码
class Solution(object):
def getHappyString(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
resStr = "" #存放结果字符串
if(k>3*2**(n-1)):return "" #长度为n时,一共有3*2**(n-1)个开心字符串
abclst = ["a", "b", "c"]
# 从第一个位置往后找
group_num = 3 #三大组,分别以a、b、c开头
groupmem_num = 2 ** (n - 1) #每一大组共2**(n - 1)个字符串
judgelst = [] # 判断k在第几组
groupfirst = 1
chooselst = [['b','c'], ['a', 'c'], ['a', 'b']] #当前位置为abc时分别可以对应的后续字符
while (len(resStr) != n): #当结果字符串长度不为n时
if (len(resStr) > 0): #已确定开头
group_num = 2 #当前字符后的小组数
groupmem_num = 2 ** (n - 1 - len(resStr)) #以当前resStr开头的开心字符串总个数
for i in range(0, group_num):
judgelst.append(i * groupmem_num + groupfirst) #[1, 1*groupmem_num+1, ...] #当前分组,用来判断k在第几组
for i in range(0, group_num):
if (i < group_num - 1):
if (k >= judgelst[i] and k < judgelst[i + 1]): #k在第i组范围中
groupfirst = judgelst[i] #记录组首号
if (len(resStr) != 0):
resStr += chooselst[abclst.index(resStr[len(resStr)-1])][i]
else:
resStr += abclst[i]
break
else:
if (k >= judgelst[i]):
groupfirst = judgelst[i]
if (len(resStr) != 0):
resStr += chooselst[abclst.index(resStr[len(resStr) - 1])][i]
else:
resStr += abclst[i]
break
judgelst = []
return resStr