[牛客网习题练习]
此系列文章仅是对个人学习的记录如有错误望大家指正与谅解。
1.题目描述:输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。
数据范围:
数据范围:n<10
要求:空间复杂度 O(n!),时间复杂度 O(n!)
输入描述:输入一个字符串,长度不超过10,字符只包括大小写字母。
2.代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @return string字符串一维数组
* @return int* returnSize 返回数组行数
*/
static int top = 0; //设置静态变量初始化
static int tmpIdx = 0;//设置静态变量初始化
int cmpstr(char* a, char* b) {
return *a - *b;
}
int perm(char** ans, char* str, char* tmp , int* vis) {
//tmp满了加入输出
int slen = strlen(str);
if (strlen(tmp) == slen) {
ans[top] = (char*)malloc(sizeof(char) * slen);
//printf("\n----- %s\n", tmp);
strcpy(ans[top++], tmp);
return 0;
}
//遍历所有元素选取一个加入
for(int i=0;i<slen;i++){
//printf("%d, ", i);
//printf("vis = %d, ", vis[i]);
if (vis[i]) { continue; }
if (i > 0 && str[i - 1] == str[i] && !vis[i - 1]) { continue; }
vis[i] = 1;
tmp[tmpIdx] = str[i];
tmp[tmpIdx + 1] = '\0';
//printf("%s, \n", tmp);
tmpIdx++;
perm(ans, str, tmp, vis);
vis[i] = 0;
tmpIdx--;
}
return 0;
}
char** Permutation(char* str, int* returnSize) {
// write code here
if (str == NULL) {
*returnSize = 0;
return NULL;
}
char** ans = NULL;
int slen = strlen(str);
ans = (char**)malloc(sizeof(char*) * 3628800);
//先排序
qsort(str, slen, sizeof(char), cmpstr);
//printf("%s",str);
//递归找str 的全排列
//临时数组tmp
char tmp[10];
//字符是否使用过
int vis[10] = { 0 };
perm(ans, str, tmp, vis);
*returnSize = top;
return ans;
}
知识点
char* char** char
区别
char*
字符型指针,指向一个字符;
数据在内存中的存储区域
1、栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
2、堆:就是那些由new或malloc分配的内存块,在不适用时,要手动用delete或free来释放内存区域。
3、全局/静态存储区:全局变量和静态变量被分配到同一块内存中,他们共同占用同一块内存区。
4、常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
char**
最常使用在main函数中:
int main(int argc,char**argv);
等同于int main(int argc,char*argv[])
等同于int main(int argc,string argv)
(C语言中并不直接包含字符串类型,此处便于理解,所以使用string类型)
char
是字符变量的说明符
字符变量的取值是字符常量,即单个字符。字符变量的类型说明符是char
。字符变量类型说明的格式和书写规则都与整型变量相同。