forked from rost0413/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCombination_Sum.cpp
More file actions
151 lines (132 loc) · 4.25 KB
/
Combination_Sum.cpp
File metadata and controls
151 lines (132 loc) · 4.25 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Author: Weixian Zhou, ideazwx@gmail.com
Date: June 26, 2012
Problem: Combination Sum
Difficulty: Medium
Source: http://www.leetcode.com/onlinejudge
Notes:
Given a set of candidate numbers (C) and a target number (T), find all unique
combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … ,ak) must be in non-descending order.
(ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]
Solution:
It's variant of classic knapsack problem. The initialization of sum matrix is following:
0 1 2 3 4 5 6 7
0 1 0 0 0 0 0 0 0
2 1
3 1
6 1
7 1
path: 1 means from top, 2 means from left, 3 means from both top and left, -1
means path not exists;
Is there a better ways to construct the path?
*/
#include <vector>
#include <set>
#include <climits>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
class Solution {
public:
bool **sum;
int **path;
set<vector<int> > result;
void searchPath(int i, int j, vector<int> p, vector<int> &candidates) {
if (j == 0) {
sort(p.begin(), p.end());
result.insert(p);
return;
}
if (path[i][j] == 1) {
//p.push_back(candidates[i - 2]);
searchPath(i - 1, j, p, candidates);
}
else if (path[i][j] == 2) {
p.push_back(candidates[i - 1]);
searchPath(i, j - candidates[i - 1], p, candidates);
}
else if (path[i][j] == 3) {
searchPath(i - 1, j, p, candidates);
p.push_back(candidates[i - 1]);
searchPath(i, j - candidates[i - 1], p, candidates);
}
return;
}
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
result.clear();
sum = new bool* [candidates.size() + 1];
path = new int* [candidates.size() + 1];
for (size_t i = 0; i < candidates.size() + 1; i++) {
sum[i] = new bool[target + 1];
path[i] = new int[target + 1];
}
// initialize
for (size_t i = 0; i < candidates.size() + 1; i++) {
sum[i][0] = true;
path[i][0] = 0;
}
for (int i = 1; i < target + 1; i++) {
sum[0][i] = false;
path[0][i] = -1;
}
// dynamic programming, construct the sum matrix and path matrix.
for (size_t i = 1; i < candidates.size() + 1; i++) {
for (int j = 1; j< target + 1; j++) {
if (j - candidates[i - 1] < 0) {
sum[i][j] = sum[i - 1][j];
if (sum[i - 1][j])
path[i][j] = 1;
else
path[i][j] = -1;
}
else {
if (sum[i - 1][j] && sum[i][j - candidates[i - 1]]) {
sum[i][j] = true;
path[i][j] = 3;
}
else if (sum[i][j - candidates[i - 1]]) {
sum[i][j] = true;
path[i][j] = 2;
}
else if (sum[i - 1][j]) {
sum[i][j] = true;
path[i][j] = 1;
}
else {
sum[i][j] = false;
path[i][j] = -1;
}
}
}
}
// construct the path from path matrix.
for (size_t i = 1; i < candidates.size() + 1; i++) {
if (path[i][target] != -1) {
vector<int> p;
searchPath(i, target, p, candidates);
}
}
// delete
for (size_t i = 0; i < candidates.size() + 1; i++) {
delete[] sum[i];
delete[] path[i];
}
delete[] sum;
delete[] path;
vector<vector<int> > vec;
vec.resize(result.size());
copy(result.begin(), result.end(), vec.begin());
return vec;
}
};