回溯法、另辟蹊径法 求数组的全排序

简介: 回溯法、另辟蹊径法 求数组的全排序

一、回溯法【路径,选择条件,结束条件】


回溯法,其实也是决策树,核心代码,就是for循环里面的递归,在递归调用之前【做出选择】,递归调用之后【撤销选择】

# 核心代码
result = []
def backtrack(路径,选择列表):
  if 满足条件:
    result.add(路径)
    return
  for 选择 in 选择列表:
    做选择
    backtrack(路径,选择列表)
    撤销选择

完整代码:


public class Permute {
    List<List<Integer>> res = new ArrayList<List<Integer>>();
    public List<List<Integer>> permute(int[] nums) {
        if (nums == null || nums.length ==0) return res;
        helper(nums,new ArrayList<Integer>());
        return res;
    }
    private void helper(int[] nums, ArrayList<Integer> tmp) {
        if (tmp.size() == nums.length){
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (tmp.contains(nums[i])) continue;
            tmp.add(nums[i]);
            helper(nums,tmp);
            tmp.remove(tmp.size()-1);
        }
    }
}


二、另辟蹊径新方法【搞怪的方法,很简单实用】


有时候,我觉得暴力一点也很好,但是我看到很多暴力的代码,需要比较交换很多次,严重的影响的代码的阅读,我想出了一个直接利用最大值循环,并利用Collections.shuffle的方法,因为最后的全排序的值时固定的,利用一个set集合,当达到了这个之后,直接退出循环就好。

你想到这个思想的小问题在哪里吗?

问题:只能计算输出没有重复元素的数组


public static void permute2(int[] nums) {
        if (nums == null || nums.length == 0) {
            //return new ArrayList<>();
        }
        // 共有多少种情况
        int sum = 1;
        for (int i = nums.length; i>0; i--) {
            sum = sum * i;
        }
        System.out.println(sum);
        ArrayList<Integer> list = new ArrayList<>();
        for (int num : nums) {
            list.add(num);
        }
        Set<List<Integer>> set = new HashSet<>();
        for (int i = 0; i < 3000000; i++) {
            Collections.shuffle(list);
            ArrayList<Integer> templist = new ArrayList<>(list);
            set.add(templist);
      // set集合的大小 = 指定的数量  退出循环
            if (set.size() == sum){
                break;
            }
            System.out.println(i);
        }
        System.out.println(set);
    }

执行结果:最终执行了10次就退出循环了 【每次执行总次数不一样】


5ecc1f6321bb47059f5a385e68aa3e60.png

677efbc895fd48a3943dd5c2eb71b13f.png

目录
相关文章
|
7月前
|
人工智能 算法
【算法分析与设计】递归与分治策略(二)
【算法分析与设计】递归与分治策略
|
8月前
|
算法
建筑抢修 (大根堆+贪心+优先队列+快速排序+2重思想比较)
建筑抢修 (大根堆+贪心+优先队列+快速排序+2重思想比较)
26 0
|
7月前
|
机器学习/深度学习 算法 编译器
【算法分析与设计】递归与分治策略(一)
【算法分析与设计】递归与分治策略
|
10月前
|
搜索推荐
图解:快速排序算法之双边循环法
之前我们学习了冒泡排序,有没有比冒泡排序更快的排序算法呢?当然有,例如快速排序,归并排序,堆排序。接下来即将介绍的快速排序就是由冒泡排序演变而来的。
116 0
图解:快速排序算法之双边循环法
|
算法 搜索推荐
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
106 0
|
7月前
|
算法 搜索推荐 Windows
【算法分析与设计】递归与分治策略(三)
【算法分析与设计】递归与分治策略
|
10月前
|
存储 搜索推荐 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(二)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
102 0
|
10月前
|
搜索推荐 算法 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(一)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
136 0
|
存储 算法 索引
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆
100 0
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆
|
存储 算法
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)