【leetcode】77. 组合

在这里插入图片描述

我用的方法是 搜索回溯的方法。

/**
 * @Auther: Mason
 * @Date: 2020/09/08/8:12
 * @Description:
 */
class Solution {
    
    
    public static void main(String[] args) {
    
    
        Solution s = new Solution();
        List<List<Integer>> list = s.combine(4, 2);
        System.out.println(list.toString());

    }


    public List<List<Integer>> combine(int n, int k) {
    
    
        List<List<Integer>> res = new LinkedList<>();
        boolean[] candidate = new boolean[n + 1]; // 记录有没有被选中,如果为true,就为被选中了。
        for (int i = 1; i <= n; i++) {
    
    
            LinkedList<Integer> tmp = new LinkedList<>();
            tmp.add(i);
            candidate[i] = true;
            dfs(candidate, res, 1, k, tmp, n, i); // 搜索回溯。深度优先遍历的方法。能够将剩余的k-1个数,放到tmp中。
            candidate[i] = false;
        }
        return res;
    }

    // ii 表示 刚刚添加的 位置。
    private void dfs(boolean[] candidate, List<List<Integer>> res, int count, int k, LinkedList<Integer> tmp, int n,int ii) {
    
    
        // 现在已经 放到tmp中 count 个元素了。
        if (count == k) {
    
    
            LinkedList<Integer> clone = new LinkedList<>(tmp);
            res.add(clone);
            return;
        }

        if(ii == n) return; // 说明 已经添加到 最后了,但是 个数没有到 k 个

        // count < k  说明还没有放到位。
        for (int i = ii; i <= n; i++) {
    
    
            if (!candidate[i]) {
    
      // 说明没有被选中。
                tmp.add(i);
                candidate[i] = true;
                dfs(candidate, res, count + 1, k, tmp, n, i); // 深度优先遍历。
                // ------------------------------回溯
                candidate[i] = false;
                tmp.remove(tmp.size() - 1);
            }
        }
    }
}

在这里插入图片描述

速度有点慢,考虑剪枝来提速一下:

在这里插入图片描述

在这里插入图片描述

/**
 * @Auther: Mason
 * @Date: 2020/09/08/8:12
 * @Description:
 */
class Solution {
    
    
    public static void main(String[] args) {
    
    
        Solution s = new Solution();
        List<List<Integer>> list = s.combine(4, 2);
        System.out.println(list.toString());

    }


    public List<List<Integer>> combine(int n, int k) {
    
    
        List<List<Integer>> res = new LinkedList<>();
        boolean[] candidate = new boolean[n + 1]; // 记录有没有被选中,如果为true,就为被选中了。
        for (int i = 1; i <= n; i++) {
    
    
            LinkedList<Integer> tmp = new LinkedList<>();
            tmp.add(i);
            candidate[i] = true;
            dfs(candidate, res, 1, k, tmp, n, i); // 搜索回溯。深度优先遍历的方法。能够将剩余的k-1个数,放到tmp中。
            candidate[i] = false;
        }
        return res;
    }

    // ii 表示 刚刚添加的 位置。
    private void dfs(boolean[] candidate, List<List<Integer>> res, int count, int k, LinkedList<Integer> tmp, int n,
                     int ii) {
    
    
        // 现在已经 放到tmp中 count 个元素了。
        if (count == k) {
    
    
            LinkedList<Integer> clone = new LinkedList<>(tmp);
            res.add(clone);
            return;
        }

        if ((n - ii) < (k - count)) return;

        // count < k  说明还没有放到位。
        for (int i = ii; i <= n; i++) {
    
    
            if (!candidate[i]) {
    
      // 说明没有被选中。
                tmp.add(i);
                candidate[i] = true;
                dfs(candidate, res, count + 1, k, tmp, n, i); // 深度优先遍历。
                // ------------------------------回溯
                candidate[i] = false;
                tmp.remove(tmp.size() - 1);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Mason97/article/details/108461094