0077组合 Marathon

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

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

示例 1:

输入:n = 4, k = 2
输出:

[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations

参考:

python

# 0077.组合


class Solution:
    def combine(self, n: int, k: int) ->[[int]]:
        """
        回溯法-解决k层循环问题
        :param n:
        :param k:
        :return:
        """
        res = []
        path = []

        def backtracking(n, k, startIndex):
            if len(path) == k:
                res.append(path[:])
                return
            for i in range(startIndex, n+1):
                path.append(i)
                backtracking(n, k, i+1)
                path.pop() # 回溯

        backtracking(n, k, 1)
        return res

class Solution1:
    def combine(self, n: int, k: int) ->[[int]]:
        """
        回溯法-解决k层循环问题-剪枝优化版本
        :param n:
        :param k:
        :return:
        """
        res = []
        path = []

        def backtracking(n, k, startIndex):
            if len(path) == k:
                res.append(path[:])
                return
            # for广度遍历时,不必到n,根据k决定深度,最后可以遍历的起始值应该为 n-(k-len(path))+1
            for i in range(startIndex, n-(k-len(path))+2):
                path.append(i)
                backtracking(n, k, i+1)
                path.pop() # 回溯

        backtracking(n, k, 1)
        return res

golang

package backTrack

var res [][]int
// 回溯法-不剪枝
func combine(n, k int) [][]int {
	if n <= 0 || k <= 0 || k > n {
		return res
	}
	backtrack(n, k, 1, []int{})
	return res
}

func backtrack(n,k,startIndex int, track []int)  {
	if len(track) == k {
		tmp := make([]int, k)
		copy(tmp, track)
		res = append(res, tmp)
	}
/*
	if len(track)+n-startIndex+1 < k {
		return
	}
*/
	for i:=startIndex;i<=n;i++ {
		track = append(track, i)
		backtrack(n,k,i+1,track)
		track = track[:len(track)-1]
	}

}

// 带剪枝回溯
func backtrack1(n,k,startIndex int, track []int)  {
	if len(track) == k {
		tmp := make([]int, k)
		copy(tmp, track)
		res = append(res, tmp)
	}
	// i只需要满足 最后一个遍历值为 n-(k-len(tarck))+1
	if len(track)+n-startIndex+1 < k {
		return
	}
	for i:=startIndex;i<=n;i++ {
		track = append(track, i)
		backtrack(n,k,i+1,track)
		track = track[:len(track)-1]
	}

}


原文地址:https://www.cnblogs.com/davis12/p/15584622.html