排列组合这种问题似乎用回溯法比较合适,括号只有左括号和或右扣号,把左扣号定好了,右括号也就定好了。
用一个栈来存中间结果,优先放左扣号,符合条件输出后回溯。
#include <stdio.h> int main(int argc, char *argv[]) { int n = atoi(argv[1]); char s[10000]; int si = -1; //未放入栈的左括号数 int left_count = n; int i = 0; while (1) { if (left_count > 0) { //左括号还没放完,继续放 s[++si] = ‘(‘; --left_count; continue; } //左括号已经放完了,可以输出了 for (i = 0; i <= si; i++) { printf("%c", s[i]); } for (i = si + 1; i < n * 2; i++) { printf(")", s[i]); } printf("\n"); //开始回溯, 直到能将某一个左扣号变成右扣号 while (si >= 0) { if (s[si] == ‘(‘) { //s[0]到s[si-1]中,左括号数超过一半,才能将s[si]变成左扣号 if ((n - left_count - 1) * 2 > si) { s[si] = ‘)‘; left_count++; break; } left_count++; } si--; } if (si < 0) { //回溯不到了 break; } } }
输出结果:
[email protected]$ ./a.out 1
()
[email protected]$ ./a.out 2
(())
()()
[email protected]$ ./a.out 3
((()))
(()())
(())()
()(())
()()()
[email protected]$
./a.out 1
()
./a.out 2
(())
()()
./a.out 3
((()))
(()())
(())()
()(())
()()()
时间: 2024-11-05 12:17:47