• 代码随想录Day22 | Leetcode39 组合总和、Leetcode40 数组总和II | Leetcode131 分割回文串


    上题

    39. 组合总和 - 力扣(LeetCode)

    40. 组合总和 II - 力扣(LeetCode)

    131. 分割回文串 - 力扣(LeetCode)

    第一题

    1. 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
    2. candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
    3. 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
    4. 示例 1
    5. 输入:candidates = [2,3,6,7], target = 7
    6. 输出:[[2,2,3],[7]]
    7. 解释:
    8. 23 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    9. 7 也是一个候选, 7 = 7
    10. 仅有这两种组合。
    11. 示例 2
    12. 输入: candidates = [2,3,5], target = 8
    13. 输出: [[2,2,2,2],[2,3,3],[3,5]]
    14. 示例 3
    15. 输入: candidates = [2], target = 1
    16. 输出: []

    思路

    • 数组从小到大排序
    • 每添加一个数i就用target-i,小于0则停止本轮递归
    • target-i > 0则进入下一层递归

    代码

    1. class Solution:
    2. """
    3. 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
    4. candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
    5. 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
    6. 示例 1:
    7. 输入:candidates = [2,3,6,7], target = 7
    8. 输出:[[2,2,3],[7]]
    9. 解释:
    10. 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    11. 7 也是一个候选, 7 = 7 。
    12. 仅有这两种组合。
    13. 示例 2:
    14. 输入: candidates = [2,3,5], target = 8
    15. 输出: [[2,2,2,2],[2,3,3],[3,5]]
    16. 示例 3:
    17. 输入: candidates = [2], target = 1
    18. 输出: []
    19. """
    20. def combinationSum(self, candiates, target):
    21. result = []
    22. res = []
    23. n = len(candiates)
    24. def dfs(i, s):
    25. if s == 0:
    26. result.append(res.copy())
    27. return
    28. for j in range(i, n):
    29. if s - candiates[j] < 0:
    30. break
    31. res.append(candiates[j])
    32. dfs(j, s-candiates[j])
    33. res.pop()
    34. candiates.sort()
    35. dfs(0, target)
    36. return result
    37. if __name__ == '__main__':
    38. test = Solution()
    39. candidates = [[2, 3, 6, 7], [2, 3, 5], [2]]
    40. target = [7, 8, 1]
    41. for i in range(len(candidates)):
    42. print(test.combinationSum(candidates[i], target[i]))

    第二题

    1. 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
    2. candidates 中的每个数字在每个组合中只能使用 一次 。
    3. 注意:解集不能包含重复的组合。
    4. 示例 1:
    5. 输入: candidates = [10,1,2,7,6,1,5], target = 8,
    6. 输出:
    7. [
    8. [1,1,6],
    9. [1,2,5],
    10. [1,7],
    11. [2,6]
    12. ]
    13. 示例 2:
    14. 输入: candidates = [2,5,2,1,2], target = 5,
    15. 输出:
    16. [
    17. [1,2,2],
    18. [5]
    19. ]

    思路

    • 数组从小到大排序
    • 不能重复使用则下一个递归改为dfs(j+1)即可
    • 重复数字产生的结果是一样的,遇到重复数字跳过,s = [2,2,4,4],s[i] == s[i-1]时跳过当前数字
    • target - s[i] < 0时结束本次递归循环,数组是从小到大排序的,往后的数字也一定不满足

    代码

    1. class Solution:
    2. """
    3. 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
    4. candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
    5. 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
    6. 示例 1:
    7. 输入:candidates = [2,3,6,7], target = 7
    8. 输出:[[2,2,3],[7]]
    9. 解释:
    10. 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    11. 7 也是一个候选, 7 = 7 。
    12. 仅有这两种组合。
    13. 示例 2:
    14. 输入: candidates = [2,3,5], target = 8
    15. 输出: [[2,2,2,2],[2,3,3],[3,5]]
    16. 示例 3:
    17. 输入: candidates = [2], target = 1
    18. 输出: []
    19. """
    20. def combinationSum2(self, candiates, target):
    21. result = []
    22. res = []
    23. n = len(candiates)
    24. def dfs(i, s):
    25. if s == 0:
    26. result.append(res.copy())
    27. return
    28. for j in range(i, n):
    29. if s - candiates[j] < 0:
    30. break
    31. if j > i and candiates[j] == candiates[j-1]:
    32. continue
    33. res.append(candiates[j])
    34. dfs(j+1, s-candiates[j])
    35. res.pop()
    36. candiates.sort()
    37. dfs(0, target)
    38. return result
    39. if __name__ == '__main__':
    40. test = Solution()
    41. candidates = [[10, 1, 2, 7, 6, 1, 5], [2, 5, 2, 1, 2]]
    42. target = [8, 5]
    43. for i in range(len(candidates)):
    44. print(test.combinationSum2(candidates[i], target[i]))

    第三题

    1. 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
    2. 回文串 是正着读和反着读都一样的字符串。
    3. 示例 1
    4. 输入:s = "aab"
    5. 输出:[["a","a","b"],["aa","b"]]
    6. 示例 2
    7. 输入:s = "a"
    8. 输出:[["a"]]

    思路

    • 看到了个很有意思的思路,"abcd" -> ['a', 'b', 'c', 'd']看成选哪个逗号即可,这样就可以用选或不选以及下一个选什么的思路解题
    • 需要注意的是每次分割需要保证每个子串都是回文,换过来看就是,如果当前选出的某个子串不是回文,就可以结束本次递归

    代码

    1. class Solution:
    2. """
    3. 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
    4. 回文串 是正着读和反着读都一样的字符串。
    5. 示例 1:
    6. 输入:s = "aab"
    7. 输出:[["a","a","b"],["aa","b"]]
    8. 示例 2:
    9. 输入:s = "a"
    10. 输出:[["a"]]
    11. """
    12. def partition(self, s):
    13. result = []
    14. res = []
    15. n = len(s)
    16. def dfs(i):
    17. if i == n:
    18. result.append(res.copy())
    19. return
    20. # 列举每个子串的结束位置
    21. for j in range(i, n):
    22. re = s[i:j+1]
    23. # 当前字串是回文才需要往后搜索,否则即使后面存在回文,最终产生的结果集一定有一个不是回文
    24. if re == re[::-1]:
    25. res.append(re)
    26. dfs(j+1)
    27. res.pop()
    28. dfs(0)
    29. return result
    30. def partition1(self, s):
    31. result = []
    32. res = []
    33. n = len(s)
    34. def dfs(i, start):
    35. if i == n:
    36. result.append(res.copy())
    37. return
    38. # 不选每个字符之间的逗号,直接选到最后一个字符,即s[0:n]
    39. if i < n-1:
    40. dfs(i+1, start)
    41. # 选每个字符之间的逗号
    42. re = s[start:i+1]
    43. if re == re[::-1]:
    44. res.append(re)
    45. # 递归的两个指针起始位置需要一样
    46. dfs(i+1, i+1)
    47. res.pop()
    48. dfs(0, 0)
    49. return result
    50. if __name__ == '__main__':
    51. test = Solution()
    52. s = ["aab", "a"]
    53. for i in s:
    54. print(test.partition1(i))

    总结

    曾经觉得很头疼的回溯,现在越来越顺手

  • 相关阅读:
    数据库面试题之Mysql
    隐私保护协议
    【牛客】【扑克牌的大小】
    【多线程】线程与进程、以及线程进程的调度
    深度学习经典网络:GoogleNet
    编译tolua——3、以pbc为例子,添加第三方库
    SpringBoot集成Kafka——如此简单
    C++ ++ 和 -- 运算符重载
    linux压缩解压命令
    dotnet 委托的实现解析
  • 原文地址:https://blog.csdn.net/qq_41502639/article/details/136521722