两个问题:n对括号有多少种匹配方式与与最长递减子序列

一.n对括号有多少种匹配方式

首先想到的思路就是列出所有可能并对符合条件的进行计数。考虑采用回溯法,即将括号列表看做是字符串,对于字符串i位来说:要么是左括号→ 递归到i+1位;要么是右括号,递归到i+1位。之后所有位都列好后进行判断,是否符合条件。在统计过程中如果某个步骤右括号的数目大于左边括号的数目,或者统计完成后左右括号数目不等,则不符合条件。代码如下。

#include 
using namespace std;
//微软44题
bool judgeparent(char a[],int n){
	int leftnum=0,rightnum=0;
	for(int i=0;i<2*n;i++){
		if(a[i] == 'l'){
			++leftnum;
		}
		else if(a[i]== 'r'){
			++rightnum;
		}
		if(rightnum > leftnum)
			return false;
	}
	if(leftnum==n && rightnum==n){
		return true;
	}
	else
		return false;
}

void calsum(int current,int n,char a[],int &cnt){
	if(current == 2*n){
		if(judgeparent(a,n)){
			++cnt;
		}
		return;
	}
	a[current] = 'l';
	calsum(current+1,n,a,cnt);
	a[current] = 'r';
	calsum(current+1,n,a,cnt);
}



int main(){
	int n,cnt =0;
	cout<<"please input num of parent:"<>n;
	char *a = (char *)malloc(2*n);
	memset(a,0,2*n);
	calsum(0,n,a,cnt);
	cout<
测试结果:2,2

二.求数组的最长递减子序列。例如{9,4,3,2,5,4,3,2}最长序列为{9,5,4,3,2}

这道题有两种解法。先看看编程之美提到中的动态规划解法(但对应的题目是求递增序列,其实都是类似的解法)。

比如已经知道5之前的递减序列为9,4,3,2。而5只会和2进行对比来判定是否可以加入递减序列,得到结论:一.9,4,3,2只是之前状态的总结;二.未来的状态只能通过现在状态来影响。所以采用动态规划解法。设定数组Lis[i]表示以a[i]为结尾的最大递减子序列的长度,则Lis[i+1]有两种情况:若a[i+1}大于所有的a[k](k>=0&&k

最长递减序列的输出:可以在过程中求得最长递减子序列的最后一个数,然后向前递归,满足a[i+1]代码如下:

#include 
using namespace std;

void PrintArray(int a[],int Lis[],int pos){
	for(int i =pos-1;i>=0;i--){
		if( (Lis[pos] = Lis[i]+1) && a[pos]Lis[pos])
					pos = i;
			}
		}
	}
	PrintArray(a,Lis,pos);
	free(Lis);
}



int main(){
	int a[] = {9,4,3,2,5,4,3,2};
	FindMaxDecrease(a,8);
	system("PAUSE");
	return 1;
}
测试结果为9,5,4,3,2

另外一种解法也是用Lis[i]数组表示以a[i]结尾的最长递减子序列,不同的是用二分查找来寻找每个a[i]的插入位置来更新List[i],这样在最后输出时直接通过List[i]来得到最长递减子序列(不知道大牛想出这样的算法出于何种考虑)。代码如下:

#include 
using namespace std;

int BinarySearch(int a[],int key,int n){
	int begin = 0;
	int end = n-1;
	while(begin <= end){
		int mid = (begin+end)>>1;
		if(key > a[mid])
			end = mid-1;
		else if(key < a[mid])
			begin = mid+1;
		else 
			return mid;
	}
	return begin;
}

void FindMaxDecrease(int a[],int n){
	int *Lis = (int *)malloc(sizeof(int)*n);
	int *temp =(int *)malloc(sizeof(int)*n);
	temp[0] =a[0];
	Lis[0]	=1;
	int templen = 1;
	for(int i =1;i= templen)
			templen++;
	}
	int maxlen = templen;
	for(int i = n-1;i>=0;i--){
		if(templen == Lis[i]){
			temp[templen-1] = a[i];
			templen--;
		}
	}
	for(int i=0;i
测试结果为:9,5,4,3,2

你可能感兴趣的:(面试题总结)