代码随想录算法训练营第二十九天|回溯算法part 5

491. 递增子序列

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

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

class Solution {
    List> res;
    ArrayList temp;
    public List> findSubsequences(int[] nums) {
        res = new ArrayList<>();
        temp = new ArrayList<>();
        backtracking(nums,0);
        return res;
    }

    private void backtracking(int[] nums, int startIndex){
        // 递增序列大小必须大于1
        if(temp.size()>1){
            res.add(new ArrayList<>(temp));
        }
        // 对单层去重
        // 注意 nums[i] 范围是 [-100,100] 一共是201个数字
        int[] used = new int[201];
        for(int i=startIndex;i

 要注意对本层去重的技巧。每次新建一个used数组来标记本层的重复元素,想象成同一位置,一个数字。

本题不能排序,因为排完序后整个数组都成递增序列了

46. 全排列

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

class Solution {
    List> res = new ArrayList<>();
    LinkedList path = new LinkedList<>();
    boolean used[];
    public List> permute(int[] nums) {
        used = new boolean[nums.length];
        backtracking(nums);
        return res;
    }

    private void backtracking(int [] nums){
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i= 0 ;i

这是排列问题,排列和组合不同 [1,2]; [2,1] 是不同的

而且不能用startIndex,因为在第二位数上还可能用数字1.

所以用一个used 数组如果used[i] == true 那么说明这是在同一分支,就不能再用这个数字了

47. 全排列 ||

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

class Solution {
    List> res = new ArrayList<>();
    LinkedList path = new LinkedList<>();
    boolean [] used;
    public List> permuteUnique(int[] nums) {
        used = new boolean[nums.length];
        Arrays.sort(nums);
        backtracking(nums);
        return res;
    }

    private void backtracking(int []nums){
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i0&&nums[i]==nums[i-1]&&used[i-1]==false){
                continue;
            }
            // 如果同一树枝上nums[i]没有使用过那么开始处理
            if(used[i]==false){
                used[i]=true;
                path.add(nums[i]);
                backtracking(nums);
                path.removeLast();
                used[i]=false;
            }
        }
    }
}

包含重复数字,需要进行排序去重

used[i-1] == true, 说明同一树枝nums[i-1]值使用过

used[i-1] == false, 说明同一树层nums[i-1]值使用过

你可能感兴趣的:(算法,leetcode,数据结构)