"The Road to Algorithmic Clearance" - capítulo 15 método de retrocesso

Notas de estudo "The Road to Algorithm Clearance", registre seu próprio processo de escovar as perguntas, compre o livro do autor para obter conteúdo detalhado.

matriz completa

Retweet Questão 46
Dado um array nums que não contém números repetidos, retorne todas as permutações possíveis dele. Você pode retornar as respostas em qualquer ordem.

class Solution:
    def permute(self, nums: list[int]) -> list[list[int]]:
        
        res = list()
        used = set()
        n = len(nums)

        def dfs(path: list[int]):
            
            if len(path) == n:
                res.append(path[:]) # 加入的是拷贝不是引用
                return
            for i in range(n):
                if i not in used:
                    used.add(i)
                    path.append(nums[i])
                    dfs(path)
                    path.pop()
                    used.remove(i)
            
        dfs([])
        return res

nums = [1,2,3]
solu = Solution()
solu.permute(nums)
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

Arranjo Completo II

Lituo question 47
Dada uma sequência nums que pode conter números repetidos, retorne todas as permutações completas não repetidas em qualquer ordem.

class Solution:
    def permuteUnique(self, nums: list[int]) -> list[list[int]]:

        res = list()
        used = set()
        n = len(nums)
        nums.sort() # 提前排序

        def dfs(path: list[int]):
            
            if len(path) == n:
                res.append(path[:])
                return

            for i in range(n):
                # 同一个位置数字不能相同,i-1 not in used 表明这个位置i-1已经待过
                if i > 0 and nums[i] == nums[i-1] and i-1 not in used:
                    continue 
                if i not in used:
                    used.add(i)
                    path.append(nums[i])
                    dfs(path)
                    path.pop()
                    used.remove(i)
            
        dfs([])
        return res

nums = [1,1,2]
solu = Solution()
solu.permuteUnique(nums)
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]

soma combinada

Dica 39.
Dado a você uma matriz de números inteiros candidatos sem elementos repetidos e um alvo inteiro alvo, encontre todas as combinações diferentes em candidatos que podem fazer a soma dos números alvo o número alvo e retorne-os em forma de lista. Você pode retornar essas combinações em qualquer ordem.

O mesmo número de candidatos pode ser selecionado repetidamente sem limite. Duas combinações são diferentes se o número escolhido de pelo menos um número for diferente.

Para uma determinada entrada, o número de combinações diferentes que somam ao alvo é menor que 150.

Fonte: LeetCode
Link: https://leetcode.cn/problems/combination-sum
Os direitos autorais pertencem a Leetcode.com. Para reimpressões comerciais, entre em contato com a autorização oficial, para reimpressões não comerciais, indique a fonte.

# 无for循环写法,必须先排序
class Solution:
    def combinationSum(self, candidates: list[int], target: int) -> list[list[int]]:
        
        res = list()
        n = len(candidates)
        candidates.sort()

        def dfs(idx: int, cur: int, path: list[int]):

            if cur == 0: # 和为target
                res.append(path[:])
                return
            elif idx == n: # 遍历结束
                return
            
            if candidates[idx] <= cur:
                path.append(candidates[idx])
                dfs(idx, cur-candidates[idx], path)
                path.pop()
                dfs(idx+1, cur, path)
            else: # 没必要继续遍历
                return

        dfs(0, target, list())
        return res

candidates, target = [2,3,6,7], 7
solu = Solution()
solu.combinationSum(candidates, target)
[[2, 2, 3], [7]]
# for循环写法,是否排序都可
class Solution:
    def combinationSum(self, candidates: list[int], target: int) -> list[list[int]]:
        
        res = list()
        n = len(candidates)

        def dfs(idx: int, cur: int, path: list[int]):

            if cur == 0: # 和为target
                res.append(path[:])
                return
            
            for idx in range(idx, n):
        
                if candidates[idx] <= cur:
                    path.append(candidates[idx])
                    dfs(idx, cur-candidates[idx], path)
                    path.pop()

        dfs(0, target, [])
        return res


candidates, target = [2,3,6,7], 7
solu = Solution()
solu.combinationSum(candidates, target)
[[2, 2, 3], [7]]

Soma da Carteira II

Confira a questão 40.
Dado um conjunto de números de candidatos e um número-alvo, descubra todas as combinações em candidatos que podem transformar a soma dos números em um alvo.

Cada número em candidatos só pode ser usado uma vez em cada combinação.

Nota: Um conjunto de soluções não pode conter combinações duplicadas.

Fonte: LeetCode
Link: https://leetcode.cn/problems/combination-sum-ii
Os direitos autorais pertencem a LeetCode.com. Para reimpressões comerciais, entre em contato com a autorização oficial, para reimpressões não comerciais, indique a fonte.

# 不使用used的写法,依据i > idx来判断
class Solution:
    def combinationSum2(self, candidates: list[int], target: int) -> list[list[int]]:
     
        res = list()
        n = len(candidates)
        candidates.sort()
  

        def dfs(idx: int, cur: int, path: list[int]):

            if cur == 0: # 和为target
                res.append(path[:])
                return
            
            for i in range(idx, n):
                # for循环中去重,这里意味着舍弃了i-1所以不能再加入i
                if i > idx and candidates[i] == candidates[i-1]:
                    continue
                if candidates[i] <= cur:
                    path.append(candidates[i])
                    dfs(i+1, cur-candidates[i], path) # 每次进入下一层时不再考虑当前数字,避免多次使用
                    path.pop()
                else: 
                    break

        dfs(0, target, list())
        return res

candidates, target = [10,1,2,7,6,1,5], 8
solu = Solution()
solu.combinationSum2(candidates, target)
[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
# 使用used的写法
class Solution:
    def combinationSum2(self, candidates: list[int], target: int) -> list[list[int]]:
     
        res = list()
        n = len(candidates)
        candidates.sort()
        used = set()
  

        def dfs(idx: int, cur: int, path: list[int]):

            if cur == 0: # 和为target
                res.append(path[:])
                return
            
            for i in range(idx, n):
                # for循环中去重,这里意味着舍弃了i-1所以不能再加入i
                if i > 0 and candidates[i] == candidates[i-1] and i-1 not in used:
                    continue
                if candidates[i] <= cur:
                    path.append(candidates[i])
                    used.add(i)
                    dfs(i+1, cur-candidates[i], path)
                    path.pop()
                    used.remove(i)
                else: 
                    break

        dfs(0, target, list())
        return res

candidates, target = [10,1,2,7,6,1,5], 8
solu = Solution()
solu.combinationSum2(candidates, target)
[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]

Subconjunto

Lituo question 78
Você recebeu um array inteiro nums, os elementos no array são diferentes uns dos outros. Retorna todos os subconjuntos possíveis (conjuntos de potência) desta matriz.

Um conjunto de soluções não pode conter subconjuntos duplicados. Você pode retornar os conjuntos de soluções em qualquer ordem.

# 不使用for循环的写法
class Solution:
    def subsets(self, nums: list[int]) -> list[list[int]]:
        res = []
        n = len(nums)

        def dfs(idx: int, path: list[int]):
            if idx == n:
                res.append(path[:])
                return
            path.append(nums[idx])
            dfs(idx+1, path)
            path.pop()
            dfs(idx+1, path)
        
        dfs(0, list())
        return res

nums = [1,2,3]
solu = Solution()
solu.subsets(nums)
[[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []]
# 使用for循环的写法
class Solution:
    def subsets(self, nums: list[int]) -> list[list[int]]:
        res = []
        n = len(nums)

        def dfs(idx: int, path: list[int]):

            res.append(path[:])
            for i in range(idx, n):
                path.append(nums[i])
                dfs(i+1, path)
                path.pop()
            
        dfs(0, list())
        return res

nums = [1,2,3]
solu = Solution()
solu.subsets(nums)
[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]

Subconjunto II

Recupere a questão 90.
Você recebeu um array inteiro nums, que pode conter elementos repetidos. Por favor, retorne todos os subconjuntos possíveis (conjuntos de potência) do array.

Um conjunto de soluções não pode conter subconjuntos duplicados. No conjunto de solução retornado, os subconjuntos podem estar em qualquer ordem.

Fonte: LeetCode
Link: https://leetcode.cn/problems/subsets-ii
Os direitos autorais pertencem a LeetCode. Para reimpressões comerciais, entre em contato com a autorização oficial, para reimpressões não comerciais, indique a fonte.

# 不使用used的写法,依据i > idx来判断
class Solution:
    def subsetsWithDup(self, nums: list[int]) -> list[list[int]]:
        res = []
        n = len(nums)
        nums.sort()

        def dfs(idx: int, path: list[int]):
            res.append(path[:])
            for i in range(idx, n):
                if i > idx and nums[i] == nums[i-1]:
                    continue
                path.append(nums[i])
                dfs(i+1, path)
                path.pop()
            
        dfs(0, list())
        return res

nums = [1,2,2]
solu = Solution()
solu.subsetsWithDup(nums)
[[], [1], [1, 2], [1, 2, 2], [2], [2, 2]]

Caderno - Github

Acho que você gosta

Origin blog.csdn.net/cjw838982809/article/details/131924759
Recomendado
Clasificación