C语言版本 - 题解 | #没有重复项数字的全排列#

没有重复项数字的全排列

http://www.nowcoder.com/practice/4bcf3081067a4d028f95acee3ddcd2b1

今天华为机考遇到了这题, ( 非一样,不过知识点一样,相当于题目加了个拟定情境,感觉拟定情况推断解决方法.其中一题的要求就是做到顺序全排列. )


// 递归求全排列
void func(
    int *num, // 输入 一维数组
    int **Res, // 输出 一维数组
    int *res, // 递归 一维数组
    int *flag, // 排列 标记
    int numLen, // 排列 长度
    int inx, // 当前 长度
    int *p) // 输出 一维数组的下标
{
    if (inx < numLen) // 递归排列中
    {
        for (int i=0; i<numLen; i++)   
        {
            if (flag[i] == 0)
            {
                res[inx] = num[i]; // 记录
                flag[i] = 1;  // 向前!!!!!
                func(num, Res, res, flag, numLen, inx+1, p); // 递归
                flag[i] = 0; // 回溯!!!!!!
            }
        }
    }
    else
    {
        int *temp = (int *)malloc(sizeof(int) * numLen);
        memcpy(&temp[0], &res[0], sizeof(int) * numLen);
        Res[p[0]] = temp; // 指针指向拷贝的数组
        p[0] += 1; // 指针偏移,就是下标,不写成*p,写成p[0],一样,大概``
    }
}


int** permute(
    int* num, // 输入 一维数组
    int numLen, // 输入 一维数组的长度
    int* returnSize, // 返回 二维数组的一维长度
    int** returnColumnSizes )  // 返回 二维数组的二维长度
{
    // 对输入排序,之后生成的排列就有顺序了
    for(int i=0; i<numLen-1; i++)
    {
        int k=i;
        for(int j=k+1; j<numLen; j++)
        {
            if (num[k] > num[j])
            {
                k = j;
            }
        }
        if (k != i)
        {
            int temp = num[k];
            num[k] = num[i];
            num[i] = temp;
        }
    }
    
    // 求长度
    int sum = 1;
    for (int i=1; i<=numLen; i++)
        sum *= i;
    returnSize[0] = sum;
    int *col = (int *)malloc(sizeof(int) * sum);
    for (int i=0; i<sum; i++)
        col[i] = numLen;
    returnColumnSizes[0] = col;
    
    // 递归全排列
    int **Res = (int **)malloc(sizeof(int*) * sum);
    int *res = (int *)malloc(sizeof(int) * numLen);
    int *flag = (int *)malloc(sizeof(int) * numLen);
    int p = 0; 
    // 本来没想加这个的,想在递归函数里用指针偏移,不知道为什么不成功,找不到问题,最后发现换成数组的形式可以,还是数组好用
    func(num, Res, res, flag, numLen, 0, &p); // 递归
    
    return Res;
}

牛客没有题解,只能到隔壁找,找到了很多c版本的题解,学习了其中一个,复现了一下.还有一种规律是交换顺序,感觉不太好理解,还是使用标记取走的思路,也符合全排列的定义.

( 昨天在牛客里做,想看c语言版本的解析,结果没有,又看不懂c++的,结果草草略过,今天遇到时基本不会,只能现场根据印象的全排列规律,写一个递归,没有回溯的概念,所以失败了,递归总是有一半是相等的,我还好奇为什么. 今晚花了1小时,理了一边,终于搞懂了.希望下次不要再错了,不过应该没下次了,没抓住机会,抱怨一下... )

全部评论
谢谢你,真正的英雄
点赞 回复 分享
发布于 2023-01-13 15:28 湖北

相关推荐

昨天 11:07
河南大学 Java
宇宙厂 测开 n*15
丘丘给个offer:有后选后
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
评论
9
1
分享
牛客网
牛客企业服务