数学
7 整数翻转
方法一 :转化为整数
class Solution:
def reverse(self, x: int) -> int:
sign = -1 if x < 0 else 1
rev = str(abs(x))
rev = rev[::-1]
res = int(rev)
res *= sign
return res if res >= -2**31 and res <= 2**31-1 else 0
方法二:数学,看题解
DFS
39 组合总数
这个函数的主题逻辑是:
Target =T,然后从数组中找一个数n,然后在 剩下的部分target 变成了 T-n,以此类推。
函数到哪返回呢,如果目标数T=0,则找的成功,返回,如果目标数T小于C中最小的数,言外之意就是我们找到不这样的组合了,寻找失败,返回。
需要注意的是,答案要求没有重复的,如果只是这么写会变成[2,3,2],[2,2,3],[3,2,2],因此要记下 上一个数,我是从小往大找的,也就是说,
如果我已经找完n=2的情况,再去找n=3的时候,3就不应该往回再选n=2了,只能往后走,不然就会重复
方法一:回溯
#写法一:
#path 使用[1, 2] +[3]的形式添加,
#基本类型变量在传参的时候,是复制,因此变量值的变化在参数里体现就行,所以 Python3 的代码看起来没有「回溯」这个步骤
#可以理解为,是复制的,有新的地址
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates, begin, size, path, res, target):
if target < 0:
return
if target == 0:
res.append(path)
for index in range(begin, size): #从下一次begin=index,从当前搜索的数字开始遍历
dfs(candidates, index, size, path + [candidates[index]], res, target - candidates[index])
res, path = [], []
begin = 0
size = len(candidates)
dfs(candidates, begin, size, path, res, target)
return res
#写法二:
#始终只有一个path在变化
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates, begin, size, path, res, target):
if target < 0:
return
if target == 0:
res.append(path[:]) #注意这里要用拷贝
#因为变量 path 所指向的列表 在深度优先遍历的过程中只有一份 ,深度优先遍历完成以后,回到了根结点,成为空列表
for index in range(begin, size): #从下一次begin=index,从当前搜索的数字开始遍历
path.append(candidates[index])
dfs(candidates, index, size, path, res, target - candidates[index])
path.pop()
res, path = [], []
begin = 0
size = len(candidates)
dfs(candidates, begin, size, path, res, target)
return res
46 全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
方法一:回溯
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
#res = [] #则不用以res作为dfs参数
def dfs(nums, path, res):
if not nums:
res.append(path)
return
for i in range(len(nums)):
dfs(nums[:i] + nums[i+1:], path+[nums[i]], res)
path, res =[], []
dfs(nums, path, res)
return res
78 子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = []
n = len(nums)
def helper(i, tmp):
res.append(tmp)
for j in range(i, n):
helper(j + 1,tmp + [nums[j]] )
helper(0, [])
return res
贪心
55. 跳跃游戏
nums的每个数代表能跳跃的最大长度,判断是否能到达最后一个下标
方法一:遍历每个下标,并且更新能到达的最大距离,如果最大距离大于等于最后一个下标,那么最后一个下表肯定能到达
在遍历到下标 i 的时候,首先要判断 i 是否能到达
class Solution:
def canJump(self, nums: List[int]) -> bool:
max_step = 0
n = len(nums)
for i in range(n):
if i <= max_step:
max_step = max(max_step, i + nums[i])
if max_step >= n-1:
return True
else: return False #如果第i个都到达不了,后面的都不可能到达了
动态规划
62. 不同路径
一个机器人位于一个 m x n 网格的左上角 。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。
问总共有多少条不同的路径?
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[1] * n] + [[1] + [0] * (n-1) for _ in range(m-1)]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
64 最小路径和
给定一个包含非负整数的 m x n
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
方法一:动态规划
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
for i in range(m):
for j in range(n):
if i == 0 and j == 0: continue
elif i == 0: grid[i][j] += grid[i][j-1]
elif j == 0: grid[i][j] += grid[i-1][j]
else: grid[i][j] += min(grid[i-1][j], grid[i][j-1])
return grid[m-1][n-1]
70. 爬楼梯
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
class Solution:
def climbStairs(self, n: int) -> int:
if n <= 2: return n
a, b = 1, 2
for _ in range(n-2):
tmp = b
b += a
a = tmp
return b
二叉树
102
二叉树的层序遍历
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:return []
stack = [root]
res = []
while stack:
tmp = []
for _ in range(len(stack)):
node = stack.pop(0)
tmp.append(node.val)
if node.left: stack.append(node.left)
if node.right: stack.append(node.right)
res.append(tmp)
return res