• C语言力扣第46题之全排列。回溯法


    给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

    示例 1:

    输入:nums = [1,2,3]
    输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

    示例 2:

    输入:nums = [0,1]
    输出:[[0,1],[1,0]]

    示例 3:

    输入:nums = [1]
    输出:[[1]]

    提示:

        1 <= nums.length <= 6
        -10 <= nums[i] <= 10
        nums 中的所有整数 互不相同

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/permutations
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    回缩法:顾名思义,通过一次一次尝试或者结果的办法。按照条件往下执行,以达到目标。当某一步不符,或者达不到目标时,回到前一次,尝试其余的可能。这种路走不通就退回走其他的的方法就称为回溯法。
    本题目【数组的全排列】不包含重复。这道题尤其适合使用回溯的方法来求解:
    这里先要科普下,排列和组合的含义:
    排列:有序排列的元素的集合。
    组合:不管排列顺序的集合。
    通过举例来了解组合排列:
    排列举例:如1,2 ,3的排列方法A3_3 = 3! = 3 * 2 * 1 = 6种
    组合举例:如1,2,3的组合方法 C3_3 = 1种
    那么这里是排列问题:
    1,2 ,3的全排序需要做才能计算出来。
    不妨不用数学的方法来思考:
    下标[0]1 -> [1]2 -> [2]3
    第一步 每次固定一个数字在 [0]下标处,问题就从3!-> 3 * 2!
    第二部 每次固定一个数字在 [1]下标处,问题就从3!-> 321
    重复步骤1和步骤2,就能等到所有的结果。
    这样所也很抽象,不妨用具体的示例来表示;

    可能3种    可能2种  可能1种
    [0]1  ----  |
    固定        |
              [1]2 ---- |
              固定      |
                |      [2]3
                |    得到结果 --(1,2,3)
                |
               [1]3 ----|
                        |
                        [2]2
                      得到结果 --(1,3,2)

    1. void swap(int * nums,int indexA,int indexB)
    2. {
    3. int temp = nums[indexA];
    4. nums[indexA]= nums[indexB];
    5. nums[indexB]= temp;
    6. }
    7. void prem(int* nums, int numsSize, int* returnSize, int** returnColumnSizes,int** returnNums,int offset)
    8. {
    9. if(offset == numsSize)
    10. {
    11. //遍历到末尾了
    12. //申请returnNums
    13. returnNums[*returnSize] = (int *)malloc(sizeof(int ) * numsSize);
    14. //拷贝内容到returnNums
    15. memcpy(returnNums[*returnSize],nums,sizeof(int) * numsSize );
    16. //记录当前拷贝内容的长度
    17. (*returnColumnSizes)[*returnSize] = numsSize;
    18. *returnSize = *returnSize + 1;
    19. }
    20. else
    21. {
    22. //回溯算法的核心
    23. int i;
    24. for(i = offset; i < numsSize; i++)
    25. {
    26. swap(nums,i,offset);//i 和 offset 交换
    27. prem(nums,numsSize,returnSize,returnColumnSizes,returnNums,offset+1);
    28. swap(nums,i,offset);//i 和 offset 交换
    29. }
    30. }
    31. }
    32. int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
    33. {
    34. //不重复的数字的全排序
    35. //组合次数为 n!= n *( n - 1) *( n - 2) ...... 2 * 1
    36. //这样的方法适合回溯的方法
    37. //取值范围1 <= nums.length <= 6 = 6 * 5 * 4 * 3 *2 * 1 = 720中可能
    38. int **returnNums = (int **)malloc(sizeof(int *) * 721);
    39. *returnColumnSizes= (int *)malloc(sizeof(int ) * 721);
    40. *returnSize = 0;
    41. prem(nums,numsSize,returnSize,returnColumnSizes,returnNums,0);
    42. return returnNums;
    43. }

  • 相关阅读:
    备份和恢复Gitlab数据
    【智慧工地源码】基于AI视觉技术赋能智慧工地
    总结了一份Java架构师核心知识点PDF丨粉丝福利
    第 368 场 LeetCode 周赛题解
    SuperSlide系列之轮播图
    LeGo-LOAM 源码解析
    xstream实现xml和java bean 互相转换
    scrapy爬虫之网站图片爬取
    无胁科技-TVD每日漏洞情报-2022-11-4
    Huggingface——tensorboard监控训练过程
  • 原文地址:https://blog.csdn.net/qq_52505851/article/details/126064790