跳至主要內容

77, 组合

Mike大约 2 分钟Backtrackingmediumbacktracking

一、题目描述

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

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

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

示例 2
输入: n = 1, k = 1
输出: [[1]]

提示

  • 1 <= n <= 20
  • 1 <= k <= n

相关主题

  • 回溯

二、题解

方法 1: 回溯

pub fn combine(n: i32, k: i32) -> Vec<Vec<i32>> {
    const BACKTRACKING: fn(i32, i32, usize, &mut Vec<i32>, &mut Vec<Vec<i32>>) =
        |start, n, k, path, res| {
            // 剪枝
            if (n - start + 1) as usize + path.len() < k {
                return;
            }

            if path.len() == k {
                res.push(path.clone());
                return;
            }

            for i in start..=n {
                path.push(i);
                BACKTRACKING(i + 1, n, k, path, res);
                path.pop();
            }
        };

    let mut res = vec![];

    BACKTRACKING(1, n, k as usize, &mut vec![], &mut res);

    res
}

方法 2: 递归实现组合型枚举

pub fn combine(n: i32, k: i32) -> Vec<Vec<i32>> {
    const DFS: fn(i32, i32, usize, &mut Vec<i32>, &mut Vec<Vec<i32>>) =
        |start, n, k, path, res| {
            // 剪枝
            if (n - start + 1) as usize + path.len() < k {
                return;
            }

            if path.len() == k {
                res.push(path.clone());
                return;
            }

            path.push(start);
            DFS(start + 1, n, k, path, res);
            path.pop();
            DFS(start + 1, n, k, path, res);
        };

    let mut res = vec![];

    DFS(1, n, k as usize, &mut vec![], &mut res);

    res
}

方法 3: 非递归(字典序法)实现组合型枚举

pub fn combine(n: i32, k: i32) -> Vec<Vec<i32>> {
    let mut res = vec![];
    let mut path = (1..=k)
        .into_iter()
        .fold(Vec::with_capacity(k + 1), |mut path, val| {
            path.push(val as i32);
            path
        });
    path.push(n + 1);

    let mut j = 0;
    while j < k {
        res.push(path[..k].to_vec());

        j = 0;
        while j < k && path[j] + 1 == path[j + 1] {
            path[j] = j as i32 + 1;
            j += 1;
        }

        path[j] += 1;
    }

    res
}