Skip to the content.

leetcode 1286 字母组合迭代器


Contact me:

Blog -> https://cugtyt.github.io/blog/index
Email -> cugtyt@qq.com
GitHub -> Cugtyt@GitHub


请你设计一个迭代器类,包括以下内容:

一个构造函数,输入参数包括:一个 有序且字符唯一 的字符串 characters(该字符串只包含小写英文字母)和一个数字 combinationLength 。 函数 next() ,按 字典序 返回长度为 combinationLength 的下一个字母组合。 函数 hasNext() ,只有存在长度为 combinationLength 的下一个字母组合时,才返回 True;否则,返回 False。

示例:

CombinationIterator iterator = new CombinationIterator("abc", 2); // 创建迭代器 iterator

iterator.next(); // 返回 "ab"
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 "ac"
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 "bc"
iterator.hasNext(); // 返回 false

提示:

1 <= combinationLength <= characters.length <= 15
每组测试数据最多包含 10^4 次函数调用。
题目保证每次调用函数 next 时都存在下一个字母组合。

可以参考题解,这里的思路是设置一个等长的01序列,用于表示字母组合,最关键的是如何用01序列表示出组合,这里给出题解中的例子:

ab
ac
ad
bc
bd

1100
1010
1001
0110
0101
0011

二进制从大到小,只需要满足一定的1个数条件即可,所以,就从最大的2进制递减,判断1的个数,判断见下面的num1函数。设定一个标志位用于表示是否有下一个。

class CombinationIterator:

    def __init__(self, characters: str, combinationLength: int):
        self.characters = characters
        self.combinationLength = combinationLength
        self.pos = 2**len(characters) - 1
        for i in range(self.pos, 0, -1):
            if self.num1(i) == self.combinationLength:
                self.pos = i
                break
        self.N = True

    def next(self) -> str:
        result = ''.join([c for p, c in zip(
            bin(self.pos)[2:].zfill(len(self.characters)),
            self.characters) if p == '1'])
        self.N = False
        for i in range(self.pos - 1, 0, -1):
            if self.num1(i) == self.combinationLength:
                self.pos = i
                self.N = True
                break
        return result


    def hasNext(self) -> bool:
        return self.N
        
    def num1(self, num):
        count = 0
        while num:
            num = num & num - 1
            count += 1
        return count