ZhangZhihui's Blog  

Given two integers n and k, return all possible combinations of k numbers chosen from the range [1, n].

You may return the answer in any order.

 

Example 1:

Input: n = 4, k = 2
Output: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
Explanation: There are 4 choose 2 = 6 total combinations.
Note that combinations are unordered, i.e., [1,2] and [2,1] are considered to be the same combination.

Example 2:

Input: n = 1, k = 1
Output: [[1]]
Explanation: There is 1 choose 1 = 1 total combination.

 

Constraints:

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

 

My Solution:

from collections import deque


class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        combs = deque()

        i = 1
        while i <= k:
            if i == 1:
                for j in range(1, n + 1):
                    combs.append([j])
            else:
                while combs and len(combs[0]) == i - 1:
                    curr = combs.popleft()
                    for j in range(curr[-1] + 1, n + 1):
                        combs.append(curr + [j])
            
            i += 1

        return list(combs)

 

 

ChatGPT's Solution:

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        def backtrack(start: int, path: List[int]):
            if len(path) == k:
                result.append(path[:])
                return
            
            for i in range(start, n + 1):
                path.append(i)
                backtrack(i + 1, path)
                path.pop()
        
        result = []
        backtrack(1, [])
        return result

 

 

Backtracking is a general algorithmic technique for solving problems by incrementally building candidates for solutions and discarding candidates ("backtracking") as soon as it’s determined that they can’t possibly lead to a valid solution.

  • Iteration (Line 6):

    • We start from the number start and try to add each number i from start to n to the path.

    • After adding i to path, we recurse with the next number (i.e., i + 1) so that we don’t reuse the same number.

  • Backtracking (Line 9):

    • Once we’ve explored the branch where i was added to the combination, we remove it (path.pop()) to backtrack and try the next possible number. This is the key idea in backtracking—when you reach a dead end or a complete solution, you "unmake" your last choice and try something else.

Example Walkthrough:

from typing import List

def combine(n: int, k: int) -> List[List[int]]:
    def backtrack(start: int, path: List[int]):
        print('------------------------------------------------backtrack ({}, {})---------------------------------------------'.format(start, path))
        if len(path) == k:
            print('add path {} to result, '.format(path[:]), end='')
            result.append(path[:])
            print('result={}'.format(result))
            print('return')
            return
        
        for i in range(start, n + 1):
            print('add i={} to path, '.format(i), end='')
            path.append(i)
            print('recurse from i + 1: start={}, path={}'.format(i + 1, path))
            backtrack(i + 1, path)
            path.pop()
            print('removed {}, path={}'.format(i, path))
            print()
        print('**********************************************************************************************')
    
    result = []
    backtrack(1, [])
    return result

 

n = 5
k = 3
combine(n, k)

 

------------------------------------------------backtrack (1, [])---------------------------------------------
add i=1 to path, recurse from i + 1: start=2, path=[1]
------------------------------------------------backtrack (2, [1])---------------------------------------------
add i=2 to path, recurse from i + 1: start=3, path=[1, 2]
------------------------------------------------backtrack (3, [1, 2])---------------------------------------------
add i=3 to path, recurse from i + 1: start=4, path=[1, 2, 3]
------------------------------------------------backtrack (4, [1, 2, 3])---------------------------------------------
add path [1, 2, 3] to result, result=[[1, 2, 3]]
return
removed 3, path=[1, 2]

add i=4 to path, recurse from i + 1: start=5, path=[1, 2, 4]
------------------------------------------------backtrack (5, [1, 2, 4])---------------------------------------------
add path [1, 2, 4] to result, result=[[1, 2, 3], [1, 2, 4]]
return
removed 4, path=[1, 2]

add i=5 to path, recurse from i + 1: start=6, path=[1, 2, 5]
------------------------------------------------backtrack (6, [1, 2, 5])---------------------------------------------
add path [1, 2, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5]]
return
removed 5, path=[1, 2]

**********************************************************************************************
removed 2, path=[1]

add i=3 to path, recurse from i + 1: start=4, path=[1, 3]
------------------------------------------------backtrack (4, [1, 3])---------------------------------------------
add i=4 to path, recurse from i + 1: start=5, path=[1, 3, 4]
------------------------------------------------backtrack (5, [1, 3, 4])---------------------------------------------
add path [1, 3, 4] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4]]
return
removed 4, path=[1, 3]

add i=5 to path, recurse from i + 1: start=6, path=[1, 3, 5]
------------------------------------------------backtrack (6, [1, 3, 5])---------------------------------------------
add path [1, 3, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5]]
return
removed 5, path=[1, 3]

**********************************************************************************************
removed 3, path=[1]

add i=4 to path, recurse from i + 1: start=5, path=[1, 4]
------------------------------------------------backtrack (5, [1, 4])---------------------------------------------
add i=5 to path, recurse from i + 1: start=6, path=[1, 4, 5]
------------------------------------------------backtrack (6, [1, 4, 5])---------------------------------------------
add path [1, 4, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5]]
return
removed 5, path=[1, 4]

**********************************************************************************************
removed 4, path=[1]

add i=5 to path, recurse from i + 1: start=6, path=[1, 5]
------------------------------------------------backtrack (6, [1, 5])---------------------------------------------
**********************************************************************************************
removed 5, path=[1]

**********************************************************************************************
removed 1, path=[]

add i=2 to path, recurse from i + 1: start=3, path=[2]
------------------------------------------------backtrack (3, [2])---------------------------------------------
add i=3 to path, recurse from i + 1: start=4, path=[2, 3]
------------------------------------------------backtrack (4, [2, 3])---------------------------------------------
add i=4 to path, recurse from i + 1: start=5, path=[2, 3, 4]
------------------------------------------------backtrack (5, [2, 3, 4])---------------------------------------------
add path [2, 3, 4] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4]]
return
removed 4, path=[2, 3]

add i=5 to path, recurse from i + 1: start=6, path=[2, 3, 5]
------------------------------------------------backtrack (6, [2, 3, 5])---------------------------------------------
add path [2, 3, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5]]
return
removed 5, path=[2, 3]

**********************************************************************************************
removed 3, path=[2]

add i=4 to path, recurse from i + 1: start=5, path=[2, 4]
------------------------------------------------backtrack (5, [2, 4])---------------------------------------------
add i=5 to path, recurse from i + 1: start=6, path=[2, 4, 5]
------------------------------------------------backtrack (6, [2, 4, 5])---------------------------------------------
add path [2, 4, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5]]
return
removed 5, path=[2, 4]

**********************************************************************************************
removed 4, path=[2]

add i=5 to path, recurse from i + 1: start=6, path=[2, 5]
------------------------------------------------backtrack (6, [2, 5])---------------------------------------------
**********************************************************************************************
removed 5, path=[2]

**********************************************************************************************
removed 2, path=[]

add i=3 to path, recurse from i + 1: start=4, path=[3]
------------------------------------------------backtrack (4, [3])---------------------------------------------
add i=4 to path, recurse from i + 1: start=5, path=[3, 4]
------------------------------------------------backtrack (5, [3, 4])---------------------------------------------
add i=5 to path, recurse from i + 1: start=6, path=[3, 4, 5]
------------------------------------------------backtrack (6, [3, 4, 5])---------------------------------------------
add path [3, 4, 5] to result, result=[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
return
removed 5, path=[3, 4]

**********************************************************************************************
removed 4, path=[3]

add i=5 to path, recurse from i + 1: start=6, path=[3, 5]
------------------------------------------------backtrack (6, [3, 5])---------------------------------------------
**********************************************************************************************
removed 5, path=[3]

**********************************************************************************************
removed 3, path=[]

add i=4 to path, recurse from i + 1: start=5, path=[4]
------------------------------------------------backtrack (5, [4])---------------------------------------------
add i=5 to path, recurse from i + 1: start=6, path=[4, 5]
------------------------------------------------backtrack (6, [4, 5])---------------------------------------------
**********************************************************************************************
removed 5, path=[4]

**********************************************************************************************
removed 4, path=[]

add i=5 to path, recurse from i + 1: start=6, path=[5]
------------------------------------------------backtrack (6, [5])---------------------------------------------
**********************************************************************************************
removed 5, path=[]

**********************************************************************************************

 

posted on 2025-04-01 12:09  ZhangZhihuiAAA  阅读(13)  评论(0)    收藏  举报