LeetCode題解--回溯算法(三)

40. 組合總和 II

給定一個數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。

candidates 中的每個數字在每個組合中只能使用一次。

說明:

所有數字(包括目標數)都是正整數。
解集不能包含重複的組合。
示例 1:

輸入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集爲:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:

輸入: candidates = [2,5,2,1,2], target = 5,
所求解集爲:
[
[1,2,2],
[5]
]

回溯、剪枝

class Solution {
    private void backtracking(List<Integer> temp, List<List<Integer>> result, int start, int target, boolean[] visited, int[] candidates) {
        if (target == 0) {
            result.add(new ArrayList<>(temp));
        }
        for (int i = start; i < candidates.length; ++i){
            if (i != 0 && candidates[i] == candidates[i - 1] && !visited[i - 1]) {  // 去重加剪枝
                continue;
            }
            if (candidates[i] <= target) {
                temp.add(candidates[i]);
                visited[i] = true;
                backtracking(temp, result, i + 1, target - candidates[i], visited, candidates);
                visited[i] = false;
                temp.remove(temp.size() - 1);
            } else {  // 剪枝
                break;
            }
        }
    }
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(candidates);
        backtracking(new ArrayList<>(), result, 0, target, new boolean[candidates.length], candidates);
        return result;
    }
}

216. 組合總和 III

找出所有相加之和爲 n 的 k 個數的組合。組合中只允許含有 1 - 9 的正整數,並且每種組合中不存在重複的數字。

說明:

所有數字都是正整數。
解集不能包含重複的組合。
示例 1:

輸入: k = 3, n = 7
輸出: [[1,2,4]]
示例 2:

輸入: k = 3, n = 9
輸出: [[1,2,6], [1,3,5], [2,3,4]]

回溯算法

class Solution {
    private void backtracking(List<List<Integer>> result, List<Integer> temp, int k, int n, int start) {
        if (temp.size() == k && n == 0) {
            result.add(new ArrayList<>(temp));
            return;
        }
        if (temp.size() > k) {
            return;
        }
        for (int i = start; i <= 9; ++i) {
            if (i <= n) {
                temp.add(i);
                backtracking(result, temp, k, n - i, i + 1);
                temp.remove(temp.size() - 1);
            } else {
                break;
            }

        }
    }
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> result = new ArrayList<>();
        backtracking(result, new ArrayList<>(), k, n, 1);
        return result;
    }
}

78. 子集

給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

示例:

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

回溯算法

class Solution {
    private void backtracking(List<List<Integer>> result, List<Integer> temp, int[] nums, int size, int start) {
        if (temp.size() == size) {
            result.add(new ArrayList<>(temp));
            return;
        }
        for (int i = start; i < nums.length; ++i) {
            temp.add(nums[i]);
            backtracking(result, temp, nums, size, i + 1);
            temp.remove(temp.size() - 1);
        }
    }
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i <= nums.length; ++i) {
            backtracking(result, new ArrayList<>(), nums, i, 0);
        }
        return result;
    }
}

90. 子集 II

給定一個可能包含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

示例:

輸入: [1,2,2]
輸出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]

回溯算法

class Solution {
    private void backtracking(List<List<Integer>> result, List<Integer> temp, boolean[] visited, int[] nums, int start, int size) {
        if (temp.size() == size) {
            result.add(new ArrayList<>(temp));
            return;
        }
        for (int i = start; i < nums.length; ++i) {
            if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
                continue;
            }
            temp.add(nums[i]);
            visited[i] = true;
            backtracking(result, temp, visited, nums, i + 1, size);
            visited[i] = false;
            temp.remove(temp.size() - 1);
        }
    }
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        List<Integer> temp = new ArrayList<>();
        for (int i = 0; i <= nums.length; ++i) {
            backtracking(result, temp, new boolean[nums.length], nums, 0, i);
        }
        return result;
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章