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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| class Solution { public: vector<vector<int> > combinationSum2(vector<int> &num, int target) { AVLTreeNode* head = nullptr; int sum = 0; for(auto item: num) { int value = 0; bool ret = avl_search(head, item, &value); avl_insert(head, item, value+1); } vector<vector<int>> result; vector<int> buffer; buffer.reserve(num.size()/2);
AVLTreeNode* curr = head; AVLTreeNode* thread_head = nullptr; while(curr) { if(curr->left==nullptr) { if(thread_head==nullptr) thread_head = curr; curr = curr->right; continue; } AVLTreeNode* left = curr->left; while(left->right && left->right!=curr) left = left->right; if(left->right == nullptr) { left->right = curr; curr = curr->left; } else { curr = curr->right; } }
dfs(thread_head, target, buffer, result);
curr = thread_head; while(curr) { if(curr->left == nullptr) { curr = curr->right; continue; } AVLTreeNode* left = curr->left; while(left->right && left->right!=curr) left = left->right; if(left->right == curr) { left->right = nullptr; curr = curr->right; } else { assert(false && "should not here"); curr = curr->left; } } return result; } private: void dfs(AVLTreeNode* head, int target, vector<int>& tpl, vector<vector<int>>& result) { if(head==nullptr) return; int num = head->key; int i = 0;
AVLTreeNode* next = head->right; AVLTreeNode* left = next ? next->left : nullptr; if(left) { while(left->right && left->right!=next) left = left->right; if(left != head) { while(next->left) next = next->left; } }
do{ if(target==0) result.push_back(tpl); else if(target>num) dfs(next, target, tpl, result);
++i; tpl.push_back(num); target -= num; }while(i<=head->value && target >=0); tpl.resize(tpl.size()-i); } };
int main(int argc, char** argv) { vector<int> nums = {4,4,2,1,4,2,2,1,3}; int target = 6; Solution s;
auto result = s.combinationSum2(nums, target); cout << result.size() << endl;
for(auto& item : result) { cout << "size(" << item.size() << ") "; for(auto val : item) { cout << val << ", "; } cout << endl; } return 0; }
|