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

#include <string>
#include <vector>
#include <iostream>

using namespace std;

//  There are two solutions for this problem, one is simple Backtracing(Bt), the other is 
//  Dynamic Programming(DP). I was thinking the DP would be faster when the Parentheses 
//  become larger.
//  However, after test with 15+, it comes out Bt is much faster than DP.
//  
//  The reseaon here may because the result is not just one, it would takes much more times
//  generate inner results (we see for loop with push_back in DP).
//  
//  DP may faster than Bt, when we need results that less than MAXNUM again and again, for
//  This situation, we do not need to calculate again.


/********************* Backtracing Solution *********************/

vector<string> result;
void GenerateParentheses(string& p, int left, int right, int level)
{
	if (left == 0 && right == 0) 
    {
        result.push_back(p);
        return;
    }
	
    //Append left parenthese
    if (left > 0)
    {
        p[level] = '(';
        GenerateParentheses(p, left-1, right+1, level+1);
    }
	
    //Append right parenthese
    if (right > 0)
    {
        p[level] = ')';
        GenerateParentheses(p, left, right-1, level+1);
    }
}

void GenerateParentheses(int n)
{
    //initialize length of string to 2*n 
    string parenthesis(n*2,'\0');
	result.clear();
    GenerateParentheses(parenthesis, n, 0, 0);
}

/********************* Dynamic Programming Solution *********************/

#define MAXNUM 100

vector<string> dp[MAXNUM][MAXNUM];  //half of the array is not used

void GenerateParentheses(int left, int right)
{
    if (left == 0 && right == 0) 
    {
        dp[0][0].push_back("");
        return;
    }
    
    //Append left parenthese
    if (left > 0)
    {
        vector<string>& strs = dp[left-1][right+1];
        if (strs.size() <= 0)
            GenerateParentheses(left-1, right+1);
        
        for (int i = 0; i < strs.size(); ++i)
            dp[left][right].push_back('(' + strs[i]);
    }
    
    //Append right parenthese
    if (right > 0)
    {
        vector<string>& strs = dp[left][right-1];
        if (strs.size() <= 0)
            GenerateParentheses(left, right-1);
		
        for (int i = 0; i < strs.size(); ++i)
            dp[left][right].push_back(')' + strs[i]);
    }
}

vector<string>& GenerateParentheses_dp(int n)
{
    if (dp[n][0].size() <=0 )
        GenerateParentheses(n, 0);
	
    return dp[n][0];
}

int main(int argc, char** argv)
{
	//The first result maybe slow, but the rest is very fast
	for (int i = 13; i > 0; --i)
	{
		int n = i;
		GenerateParentheses(n);
		GenerateParentheses_dp(n);
		
		cout << n <<": ";
		if (result == dp[n][0])
			cout << "The same result for Backtracing and Dynamic Programming\n";
		else
			cout << "Different!!!!!!!!";
	}
	
    // for (int i = 0; i < result.size(); ++i)
    //     cout<<result[i] << '\n';
	
	return 0;
}
View Program Text


Test Status