题解 | #字符串的排列#
字符串的排列
https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7
对于字符串的排列,其实思路和BM56 有重复项数字的全排列是一样的,只不过BM56需要按字典升序排列,这里不需要。
/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串一维数组 * @return int* returnSize 返回数组行数 */ //check函数用于检查是否需要进行交换 int check(char* str,int left,int right) { while(left<right) { //如果当前检查的字符(str[left])之后有重复的字符,那么交换是没有意义的,返回0 if(str[left]==str[right]) { return 0; } right--; } //无重复字符,交换有意义,返回1 return 1; } //交换字符函数 void swap(char *str,int i,int j) { char temp=str[i]; str[i]=str[j]; str[j]=temp; } //回溯递归函数 /*参数说明 str:字符串 strLen:字符串长度 returnSize:当前已有解的个数(返回数组的长度) returnArray:返回的二维字符数组 depth:当前进行的深度 */ void backtrack(char *str,int strLen,int *returnSize,char **returnArray,int depth) { //当进行深度达到字符串长度时,表明已经达到末端,得到一种解 if(depth==strLen) { //每得到一种解,就为char类型返回数组申请一块空间,用于记录该解 returnArray[*returnSize]=(char*)malloc(sizeof(char)*strLen); //将当前字符串复制到上一步申请的空间中 memcpy(returnArray[*returnSize],str,sizeof(char)*strLen); //returnSize可以表示解的数量,所以解+1 *returnSize=*returnSize+1; } //以下为递归过程 else { int i; //i从每一次的深度开始,往后循环查询 for(i=depth;i<strLen;i++) { //当查询该到该字符能与后面某些字符交换时,进行递归进入下一层 if(check(str,i,strLen-1)==1) { //交换 swap(str,i,depth); //递归 backtrack(str,strLen,returnSize,returnArray,depth+1); //这里是回溯出来后,要对原来的字符归零(恢复原状),所以再次交换 swap(str,i,depth); } } } } //主函数 char** Permutation(char* str, int* returnSize ) { // write code here //申请一个二维的char类型数组,因为字符数量最多10个,所以解可能有10!种,为3628800 char **ret=(char**)malloc(sizeof(char*)*3628801); //获取字符串长度 int str_len=strlen(str); //初始返回char类型数组中是没有解的,设置为0 *returnSize=0; //回溯开始 backtrack(str,str_len,returnSize,ret,0); return ret; }