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]]