784. 字母大小写全排列

给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。

char **ret = NULL;
char *str = NULL;
char *S_temp = NULL;
int retSize = 0;
int *recored = NULL;
int len = 0;
int num = 0;

void isletter(char *str, int *num)  //计算字符串个数
{
    int len = strlen(str);
    int temp = 0;
    for(int i = 0; i < len; i++)
    {
        if((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
        {
            recored[temp++] = i;
        }
    }
    *num = temp;
}

void backtrace(int index, int now, int need)  //组合问题,与位置无关
{
    if(now == need)
    {
        char *temp = (char*)malloc(sizeof(char) * len);
        memcpy(temp, str, sizeof(char) * len);
        ret[retSize++] = temp;
        return;
    }

    for(int i = index; i < num; i++)
    {
        if(num - need + now < i) break;   //组合问题,与位置无关,比如说‘a1b2c’ 在需要2个字母变化的情况下,在确定第一个字母的时候,如果
                                          //遍历到第三个字母时,不需要。因为前面的情况下已经有使用第三个字符串了。
        if(str[recored[i]] > 'Z') str[recored[i]] -= 32;
        else str[recored[i]] += 32;

        backtrace(i+1, now+1, need);
        if(str[recored[i]] > 'Z') str[recored[i]] -= 32;
        else str[recored[i]] += 32;

    }

}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
char ** letterCasePermutation(char * S, int* returnSize){
    num = 0;
    retSize = 0;
    len = strlen(S);
    len++;  //包括字符串结束符
    recored = (int*)malloc(sizeof(int) * len);
    memset(recored, 0, sizeof(int) * len);
    isletter(S, &num);
    if(num == 0)  //不存在字符的情况
    {
        ret = (char **)malloc(sizeof(char*) * 1);
        char *temp = (char*)malloc(sizeof(char) * len);
        memcpy(temp, S, sizeof(char) * len);
        ret[retSize++] = temp;
        *returnSize = retSize;
        return ret;
    }
    
    ret = (char **)malloc(sizeof(char*) * 5000);
    str = (char*)malloc(sizeof(char) * len);
    memcpy(str, S, sizeof(char) * len);
    S_temp = S; 

    char *tmp = (char*)malloc(sizeof(char) * len); //包括字符串本身
    memcpy(tmp, str, sizeof(char) * len);
    ret[retSize++] = tmp;

    for(int i = 1; i <= num; i++)
    {
        backtrace(0, 0, i);
    }
    free(str);  
    free(recored);   

    *returnSize = retSize;
    return ret;

}

思路:使用回溯算法
1.先找到字符串里面的字母
2.每次变化的字母个数为1~num
3.编写回溯函数
784. 字母大小写全排列
打叉的那些如果继续遍历就会和前面的重复,所以就进行剪枝

上一篇:【PC工具】更新win10关闭更新工具Windows Update Blocker


下一篇:leetcode 397,784,898,100,101,104,108,110,111,112,226,235,257