// 全局变量
char** result;
int resultSize;
int* used;

// 比较函数用于排序
int cmp(const void* a, const void* b) {
    return *(char*)a - *(char*)b;
}

// 回溯函数
void backtrack(char* s, int len, int depth, char* current) {
    if (depth == len) {
        // 找到一个排列
        result[resultSize] = (char*)malloc(sizeof(char) * (len + 1));
        strcpy(result[resultSize], current);
        resultSize++;
        return;
    }

    for (int i = 0; i < len; i++) {
        // 剪枝条件:当前字符已使用,或者当前字符与前一个相同且前一个未使用
        if (used[i] || (i > 0 && s[i] == s[i - 1] && !used[i - 1])) {
            continue;
        }

        used[i] = 1;
        current[depth] = s[i];
        backtrack(s, len, depth + 1, current);
        used[i] = 0;  // 回溯
    }
}

/**
 * 返回所有不重复的排列
 * @param s: 输入字符串
 * @param returnSize: 返回数组的大小
 * @return: 所有排列的数组
 */
char** Permutation(char* s, int* returnSize) {
    int len = strlen(s);

    // 计算最大可能排列数:len! / (重复字符的阶乘)
    // 先简单分配一个较大的空间
    int maxSize = 1;
    for (int i = 2; i <= len; i++) {
        maxSize *= i;
    }

    // 分配内存
    result = (char**)malloc(sizeof(char*) * maxSize);
    used = (int*)calloc(len, sizeof(int));
    char* current = (char*)malloc(sizeof(char) * (len + 1));
    current[len] = '\0';

    // 先排序,让相同字符相邻
    qsort(s, len, sizeof(char), cmp);

    resultSize = 0;
    backtrack(s, len, 0, current);

    *returnSize = resultSize;
    free(current);
    free(used);
    return result;
}