一、Problem
Design an Iterator class, which has:
A constructor that takes a string characters of sorted distinct lowercase English letters and a number combinationLength as arguments.
A function next() that returns the next combination of length combinationLength in lexicographical order.
A function hasNext() that returns True if and only if there exists a next combination.
CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator.
iterator.next(); // returns "ab"
iterator.hasNext(); // returns true
iterator.next(); // returns "ac"
iterator.hasNext(); // returns true
iterator.next(); // returns "bc"
iterator.hasNext(); // returns false
Constraints:
1 <= combinationLength <= characters.length <= 15
There will be at most 10^4 function calls per test.
It’s guaranteed that all calls of the function next are valid.
二、Solution
方法一:二進制枚舉
最暴力的方法就是用回溯法所有組合預處理出來,但這裏寫一個比較新穎的做法:利用二進制位 1 來表示有字母需要選,0 表示該位置的字母不需要選。
class CombinationIterator {
char[] alps;
int n, len, tot;
public CombinationIterator(String characters, int combinationLength) {
alps = characters.toCharArray();
n = alps.length;
len = combinationLength;
tot = (1 << n) - 1;
}
public String next() {
while (tot > 0 && countOne(tot) != len)
tot--;
String res = b2s(tot);
tot--;
return res;
}
public boolean hasNext() {
return tot >= (1 << len) - 1;
}
int countOne(int bits) {
int cnt = 0;
while (bits != 0) {
bits &= (bits - 1);
cnt++;
}
return cnt;
}
String b2s(int bits) {
StringBuilder sb = new StringBuilder();
int i = 0;
while (bits != 0) {
if ((bits & 1) == 1)
sb.append(alps[n-i-1]);
i++;
bits = bits >>> 1;
}
return sb.reverse().toString();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,