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

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

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


回溯法,其实也是决策树,核心代码,就是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

目录
相关文章
|
人工智能 算法
【算法分析与设计】递归与分治策略(二)
【算法分析与设计】递归与分治策略
|
算法
建筑抢修 (大根堆+贪心+优先队列+快速排序+2重思想比较)
建筑抢修 (大根堆+贪心+优先队列+快速排序+2重思想比较)
46 0
|
1月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
21 0
|
5月前
每日一题 540. 有序数组中的单一元素
每日一题 540. 有序数组中的单一元素
|
6月前
|
移动开发 算法
二分查找之红蓝二分查找
二分查找之红蓝二分查找
|
搜索推荐
图解:快速排序算法之双边循环法
之前我们学习了冒泡排序,有没有比冒泡排序更快的排序算法呢?当然有,例如快速排序,归并排序,堆排序。接下来即将介绍的快速排序就是由冒泡排序演变而来的。
181 0
图解:快速排序算法之双边循环法
|
算法 搜索推荐 Windows
【算法分析与设计】递归与分治策略(三)
【算法分析与设计】递归与分治策略
|
搜索推荐 算法 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(一)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
210 0
|
存储 搜索推荐 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(二)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
182 0
|
Python
数组最值之谜
数组最值之谜
43 0