forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iterator-for-combination.cpp
77 lines (65 loc) · 2.01 KB
/
iterator-for-combination.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Time: O(k), per operation
// Space: O(k)
class CombinationIterator {
public:
CombinationIterator(string characters, int combinationLength)
: characters_(characters)
, combinationLength_(combinationLength)
, last_(prev(characters.cend(), combinationLength), characters.cend())
, stk_{bind(&CombinationIterator::divide, this, 0)} {
}
string next() {
iterative_backtracking();
return curr_;
}
bool hasNext() {
return curr_ != last_;
}
private:
void iterative_backtracking() {
while (!stk_.empty()) {
const auto cb = move(stk_.back());
stk_.pop_back();
if (cb()) {
return;
}
}
}
bool conquer() {
if (curr_.length() == combinationLength_) {
return true;
}
return false;
}
bool prev_divide(char c) {
curr_.push_back(c);
return false;
}
bool divide(int i) {
if (curr_.length() != combinationLength_) {
for (int j = int(characters_.length()) - (combinationLength_ - int(curr_.length()) - 1) - 1;
j >= i; --j) {
stk_.emplace_back(bind(&CombinationIterator::post_divide, this));
stk_.emplace_back(bind(&CombinationIterator::divide, this, j + 1));
stk_.emplace_back(bind(&CombinationIterator::prev_divide, this, characters_[j]));
}
}
stk_.emplace_back(bind(&CombinationIterator::conquer, this));
return false;
}
bool post_divide() {
curr_.pop_back();
return false;
}
const string characters_;
const int combinationLength_;
string curr_;
string last_;
vector<function<bool()>> stk_;
};
/**
* Your CombinationIterator object will be instantiated and called as such:
* CombinationIterator* obj = new CombinationIterator(characters, combinationLength);
* string param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/