回溯算法(排列/组合/子集)

news/2024/7/20 21:20:08 标签: leetcode, 深度优先, 算法, java

排列

无重复元素全排列

题目链接:

全排列https://leetcode.cn/problems/permutations/

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 

示例:

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

以上方示例为例子,一开始有三个元素:

每个元素都需要被选,但是选择的顺序不同,被选中的元素带有红色标记,它的下一步就不能选它本身(因为需要无重复);

为什么需要回溯呢,如果你一条道走到黑就只能得到最多一种全排列,回溯就是寻找同一层的其他路径,这样就能得到更多的全排列。

 完整代码:

java">import java.util.ArrayList;
import java.util.List;


class Solution {
    static List<List<Integer>>res=new ArrayList<>();
    static List<Integer>path=new ArrayList<>();
    static void recur(int[]nums,boolean[]v){
        //说明找到一组
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if(v[i])continue;
            v[i]=true;
            path.add(nums[i]);
            recur(nums,v);
            path.remove(path.size() - 1);
            v[i]=false;
        }
    }
    public List<List<Integer>> permute(int[] nums) {
        res.clear();
        path.clear();
        boolean[]v=new boolean[nums.length];
        recur(nums,v);
        return res;

    }

}

 有重复元素全排列

题目链接:

全排列IIhttps://leetcode.cn/problems/permutations-ii/

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

 示例:

java">输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

以[1,1,2]为例,因为需要无重复,涉及到去重操作:

java">class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>>permutes=new ArrayList<>();
        List<Integer>tmp=new ArrayList<>();
        Arrays.sort(nums);
        boolean[]v=new boolean[nums.length];
        trace(tmp,permutes,v,nums);
        return permutes;

    }
    private void trace(List<Integer>tmp, List<List<Integer>>permutes,boolean[]v,int[]nums){
        if(tmp.size()==nums.length){
            permutes.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < v.length; i++) {
            if((i!=0&&nums[i]==nums[i-1]&&!v[i-1])||v[i])continue;
            v[i]=true;
            tmp.add(nums[i]);
            trace(tmp,permutes,v,nums);
            tmp.remove(tmp.size() - 1);
            v[i]=false;
        }

    }
}

 组合

题目链接:

组合icon-default.png?t=N176https://leetcode.cn/problems/combinations/

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例:

java">输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

这里题目同一层使用过就不能使用了:

 

java">class Solution {
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> track = new ArrayList<>();
        backtrack(res, track, 1, n, k);
        return res;


    }

    static void backtrack(List<List<Integer>> res, List<Integer> track, int start, int n, int k) {
        // 当 track 大小为 k 时,满足条件
        if (track.size() == k) {
            res.add(new ArrayList<>(track));
            return;
        }

        for (int i = start; i <= n; i++) {
            track.add(i);
            backtrack(res, track, i + 1, n, k);
            track.remove(track.size() - 1);
        }
    }
}

子集

无重复元素无重复子集

子集icon-default.png?t=N176https://leetcode.cn/problems/subsets/submissions/

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例:

java">输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
java">import java.util.ArrayList;
import java.util.List;



class Solution {
    private List<Integer> path = new ArrayList<>();
    private List<List<Integer>> res = new ArrayList<>();

    public List<List<Integer>> subsets(int[] nums) {
        backtrack(nums, 0);
        return res;


    }

    private void backtrack(int[] nums, int start) {
        res.add(new ArrayList<>(path));
        for (int i = start; i < nums.length; i++) {
            path.add(nums[i]);
            backtrack(nums, i + 1);
            path.remove(path.size() - 1);
        }
    }

}

有重复元素无重复子集

题目:

子集IIicon-default.png?t=N176https://leetcode.cn/problems/subsets-ii/submissions/379274654/

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例:

java">输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
java">class Solution {
    private List<List<Integer>>res=new ArrayList<>();
    private List<Integer>track=new ArrayList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backtrack(nums,0);
        return res;


    }

    private void backtrack(int[] nums, int start) {
        
        res.add(new ArrayList<>(track));

        for (int i = start; i < nums.length; i++) {
            // 剪枝
            if (i > start && nums[i] == nums[i - 1]) continue;
            track.add(nums[i]);
            backtrack(nums, i + 1);
            track.remove(track.size() - 1);
        }
    }
}


http://www.niftyadmin.cn/n/174666.html

相关文章

提取道路 | EXCEL中从地址中提取道路名称等信息

一 前言 EXCEL是我们日常工作学习数据处理的办公软件&#xff0c;操作易上手&#xff0c;几乎人人都会用&#xff0c;EXCEL表格是处理表格数据的最佳选择。 小O地图EXCEL插件提供 地理工具 / 地址提取 功能&#xff0c;能够从地址文字中按分类提取地址词&#xff0c;用户可根据…

01分布式电源接入对配电网影响分析

说明书 MATLAB代码&#xff1a;分布式电源接入对配电网影响分析 关键词&#xff1a;分布式电源 配电网 评估 代码获取;详见博主资源 仿真平台&#xff1a;MATLAB 主要内容&#xff1a;代码主要做的是分布式电源接入场景下对配电网运行影响的分析&#xff0c;其中&…

ABC278 F - Shiritori

不懂博弈和状压DP&#xff0c;今晚加训状压DP&#xff01;博弈太难了&#xff0c;东西太多了&#xff0c;等蓝桥杯打完再说QwQF - Shiritori (atcoder.jp)题意&#xff1a;思路&#xff1a;注意到数据范围是到16&#xff0c;因此可以考虑状压DP状态设计&#xff1a;&#xff08…

Spring Bean的初始化及销毁相关注解

文章目录一、通过Bean注解指定初始化和销毁方法二、让Bean实现InitializingBean和DisposableBean接口三、使用JSR-250规范中的PostConstruct和PreDestroy注解四、BeanPostProcessor处理初始化前后的工作一、通过Bean注解指定初始化和销毁方法 在初始化和销毁方法前后进行处理的…

【刷题之路Ⅱ】牛客 NC107 寻找峰值

【刷题之路Ⅱ】牛客 NC107 寻找峰值一、题目描述二、解题1、方法1——直接遍历1.1、思路分析1.2、代码实现2、方法2——投机取巧的求最大值2.1、思路分析2.2、代码实现3、方法3——二分法3.1、思路分析3.2、代码实现一、题目描述 原题连接&#xff1a; NC107 寻找峰值 题目描…

模拟请求发生跨域问题

参考&#xff1a;传送门 问题产生&#xff1a; Access to XMLHttpRequest at ‘http://test-cms.jinhuahuolong.com/api/pages/list’ from origin ‘null’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resourc…

Cadence Allegro 导出Padstack Usage Report报告详解

⏪《上一篇》   🏡《上级目录》   ⏩《下一篇》 目录 1,概述2,Padstack Usage Report作用3,Padstack Usage Report示例3.1,Total Padstack Instances3.2,Detailed Padstack Usage4,Padstack Usage Report导出方法4.1,方法14.2,方法2

代码随想录复习——单调栈篇 每日温度 下一个更大元素12 接雨水 柱状图中最大的矩形

739.每日温度 每日温度 暴力解法双指针 def dailyTemperatures(self, temperatures: List[int]) -> List[int]:n len(temperatures)res [0] * nfor i in range(n):for j in range(i,n):if temperatures[j] < temperatures[i]: continueelse: res[i] j-ibreakreturn …