2021-05-09

力扣剑指offer38字符串的排列详细解答c语言

修改某大佬的代码

int is_repeat(char* chare_string,int start,int end){
    for(;start<end;start++){
        if(chare_string[start]==chare_string[end]) return 1;
    }
    return 0;
}
void swap(char* chare_string,int i,int j){
    char tmp=chare_string[i];
    chare_string[i]=chare_string[j];
    chare_string[j]=tmp;
}
void dfs(char* chare_string,int head,int length,char** res,int* returnSize){
    if(head==length-1){
        char* tmp=(char*)malloc(sizeof(char)*(length+1));
        strcpy(tmp,chare_string);
        res[(*returnSize)++]=tmp;
    }
for(int i=head;i<length;i++){
    if(is_repeat(chare_string,head,i)){
        continue;
    }
        swap(chare_string,head,i);
        dfs(chare_string,head+1,length,res,returnSize);
        swap(chare_string,head,i);
    }
}
char** permutation(char* s, int* returnSize){//返回值为指向字符指针的指针
    int length=strlen(s);
    *returnSize=0;
    if(s==NULL) return NULL;
    int size=1;
    for(int i=1;i<length+1;i++) size*=i;
    char** res=(char*)malloc((size+1)*sizeof(char*));
    dfs(s,0,length,res,returnSize);
    return res;
}

上述是答案:下面进行分块分析;
首先对各个变量名进行解释:
chare_string指的是被操作的字符串;
函数dfs()里面head为头节点即被操作的同一行节点;
res是一个指向字符串指针的指针;也是最后一个操作函数的返回值;
returnSize初始是0,最终变成了排序的总种类。


这里用到了深度优先搜索递归的思想;
下面是我的个人见解:
这里插入力扣上找到的比较详细的图了在这里插入图片描述
这是力扣上的图解,只能写出所有字母都不同的情况;
下面是有相同字母的图解在这里插入图片描述

下面是比较难理解的部分了:
我想swap以及is_repeat不用介绍了吧。
直接到dfs()
首先if(head==length-1){
char* tmp=(char*)malloc(sizeof(char)*(length+1));
strcpy(tmp,chare_string);
res[(*returnSize)++]=tmp;
}

这个操作虽然放在第一行但是确实递归到最后一步的操作。将经过多次dfs操作后的chare_string开辟一个tmp空间储存,又因为res[returnsize]为指向字符串的指针,则指向tmp;

for(int i=head;i<length;i++){
        if(is_repeat(chare_string,head,i)){
            continue;
        }

这个则是判断同一行节点是否存在相同的情况:如果存在可以直接跳过。因为下面的操作是交换这两者进行下一行的遍历。(如果不跳过会导致重复的结果,于题不符合)

swap(chare_string,head,i);
dfs(chare_string,head+1,length,res,returnSize);
swap(chare_string,head,i);

最后第一个swap是交换同行但是值不相同的字母顺序然后dfs交换后遍历下一行,最后一个swap则是重新换回来。再通过for语句判断与下一个字母是否相同,然后再经行上述过程。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YZzzz...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值