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

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

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


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

目录
相关文章
|
3月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
38 1
|
3月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
43 0
|
8月前
|
算法 测试技术 C#
【并集查找 图论 位运算】3108. 带权图里旅途的最小代价
【并集查找 图论 位运算】3108. 带权图里旅途的最小代价
|
7月前
每日一题 540. 有序数组中的单一元素
每日一题 540. 有序数组中的单一元素
|
算法 搜索推荐
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
218 0
|
存储 搜索推荐 算法
插入/希尔/选择/堆/冒泡/快速/归并/计数排序 && 排序原理 && 搜索树原理 && 哈希概念
插入/希尔/选择/堆/冒泡/快速/归并/计数排序 && 排序原理 && 搜索树原理 && 哈希概念
91 0
|
搜索推荐 算法 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(一)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
225 0
|
存储 搜索推荐 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(二)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
213 0
[leetcode 324] 摆动排序 II 思维+排序
[leetcode 324] 摆动排序 II 思维+排序
88 0
|
存储 算法 索引
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆
129 0
【每日挠头算法题】LeetCode 1337. 矩阵中战斗力最弱的 K 行 —— 二分 + 排序 / 堆