程序员面试金典: 9.9 递归和动态规划 9.6打印n对括号的全部有效组合
2017-01-09 14:44
274 查看
#include <iostream> #include <stdio.h> #include <vector> #include <string> #include <sstream> using namespace std; /* 问题:实现一种算法,打印n对括号的全部有效组合(即左右括号正确配对) 分析:这是卡特兰数。印象中好像是 总解法个数 =(1/n) * (2n)! / ( (n-1)! * (n+1)! ) 比如n=2, 把左括号认为为1,右括号认为0,它必须满足从任意数字n开始,前面n-1个数中1的个数>=0的个数 用递归来做,确定第一个为1,后续每次检查0和1哪个符合,需要用哈希计数。 2n*2=4n 时间复杂度为O(n) 输出: 2(2对括号) 输出: (()),()() */ const int MAXSIZE = 10000; bool isOk(int pos , char* result , int value , int n) { if(pos < 0 || value < 0 || value > 1) { return false; } int hashArr[2]; memset(hashArr , 0 , sizeof(hashArr)); for(int i = 0 ; i < pos; i++) { int ch = result[i] - '0'; if(ch > 1 || ch < 0) { continue; } hashArr[ch]++; } hashArr[value]++; int count0 = hashArr[0]; int count1 = hashArr[1]; //易漏,注意coun1的个数最多只能为n if(count1 >= count0 && count1 <= n) { return true; } else { return false; } } void getCombination(int pos , char* result , vector< string >& results , int n) { if(pos < 0 || n < 1 || NULL == result) { return; } stringstream ss; //总长度为2n if( pos == 2*n ) { result[pos] = '\0'; string sResult(result); results.push_back(sResult); } else { //摆放第pos个位置为1或0,必须满足当前摆放后,字符串中1的个数>=0的个数 for(int i = 0 ; i <= 1; i++) { if( isOk(pos , result , i , n) ) { //如果可以就递归处理 result[pos] = (char)(i + '0'); getCombination(pos + 1 , result , results , n); } } } } string turnToBracket(string& str) { if(str.empty()) { return str; } int size = str.size(); char ch; stringstream ss; for(int i = 0 ; i < size ; i++) { ch = str.at(i); if( '1' == ch ) { ss << "("; } else if('0' == ch) { ss << ")"; } } return ss.str(); } void print(vector<string>& results) { if(results.empty()) { cout << "No Result!" << endl; return; } int count = 0; for(vector<string>::iterator it = results.begin() ; it != results.end() ; it++) { if(count) { cout << "," << turnToBracket(*it); } else { cout << turnToBracket(*it); } count++; } cout << endl; } void process() { int n; vector< string > results; int pos; char result[MAXSIZE]; while(cin >> n) { pos = 0; results.clear(); getCombination(pos , result , results , n); print(results); } } int main(int argc, char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- web前端面试试题总结---其他
- 程序员面试金典第二章:链表(6) 链表环路
- 面试--排序(75)
- 程序员面试金典第二章:链表(7)回文链表
- 面试--金融支付(75)
- 程序员面试金典第二章:链表(5) 链式A+B
- Java面试题目整理
- 面试算法:获取重合列表的第一个相交节点
- 面试题之jsp九大内置对象
- 2017-01-09上午看了点儿面试的东西 感觉东西还行
- Java面试题中的关于单例模式、冒泡排序、递归
- 程序员必备简捷开发辅助工具总结
- web前端面试试题总结---css篇
- iOS 性能调优,成为一名合格iOS程序员必须掌握的技能
- Java高阶面试问题合集
- Android 开发工程师面试指南
- 程序员取悦女票的正确姿势---Tip1(iOS美容篇)
- 工作压力太大,离职就能解决了?
- 一个玩英雄联盟的java程序员这样忏悔!不!是发誓!
- OSChina 周一乱弹 ——程序员,禅师是这样说的。