算法第二十四天|回溯

491. 非递减子序列

class Solution {
      List<List<Integer>> result = new LinkedList<>();

    LinkedList<Integer> list = new LinkedList<>();

    public List<List<Integer>> findSubsequences(int[] nums) {
        if (nums.length <= 1) {
            return result;
        }
        backtracking(nums, 0);
        return result;
    }

    private void backtracking(int[] nums, int beginIndex) {
        if (list.size() >= 2) {
            result.add(new ArrayList<>(list));
        }

        if (beginIndex == nums.length) {
            return;
        }
        // 判断是否已经有相同元素存在了
        HashSet<Integer> hashSet = new HashSet<>();
        for (int i = beginIndex; i < nums.length; i++) {
            if (!list.isEmpty() && list.getLast() > nums[i] || hashSet.contains(nums[i])) {
                continue;
            }
            hashSet.add(nums[i]);
            list.add(nums[i]);
            backtracking(nums, i + 1);
            list.removeLast();
        }
        // 当前放入的元素,必须比上一个放入的元素大,才能放入
        // 如果到达末尾就返回
        // 如果list个数大于2,那么就放入result中
    }
}

使用一个HashSet来排除相同元素的再次注入

46. 全排列

 List<List<Integer>> result = new ArrayList<>();

LinkedList<Integer> list = new LinkedList<>();

public List<List<Integer>> permute(int[] nums) {
    // 1 <= nums.length <= 6  -10 <= nums[i] <= 10
    backtracking(nums, 0);
    return result;
}

private void backtracking(int[] nums, int beginIndex) {
    if (list.size() == nums.length) {
        result.add(new ArrayList<>(list));
        return;
    }

    for (int i = 0; i < nums.length; i++) {
        if (list.contains(nums[i])) {
            continue;
        }
        list.add(nums[i]);
        backtracking(nums, i + 1);
        list.removeLast();
    }

}

beginIndex没有起到任何作用

47. 全排列 II

  List<List<Integer>> result = new ArrayList<>();

    LinkedList<Integer> list = new LinkedList<>();

    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        boolean[] path = new boolean[nums.length];
        Arrays.fill(path, false);
        backtracking(nums, path);
        return result;
    }

    private void backtracking(int[] nums, boolean[] path) {
        if (list.size() == nums.length) {
            result.add(new ArrayList<>(list));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            if ((i > 0 && nums[i] == nums[i - 1]) && (!path[i - 1])) {
                continue;
            }
            if (path[i] == false) {
                path[i] = true;
                list.add(nums[i]);
                backtracking(nums, path);
                path[i] = false;
                list.removeLast();
            }

        }
    }

使用数组来标识经过的路径,当通过,设置为true

同一层时,前一个元素和当前元素相等,并且,前一个元素没有使用过。比如1,1,2

第一个元素没有使用过,当前为第二个1,那么说明是从第二个元素开始的,这个元素会重复,所以进行continue

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容