刷题记录
7.9 比特数记位
class Solution:
def countBits(self, n: int) -> List[int]:
if n==0:
return [0]
high_hit = 0
res = [0]
for i in range(1,n+1):
if i & (i-1) == 0:
high_hit = i
res.append(res[i-high_hit]+1)
return res
回文子串
求一个字符串中一共多少回文子串 中心扩展法
class Solution:
def countSubstrings(self, s: str) -> int:
n = len(s)
res = 0
def substrings(left,right,res):
while left>=0 and right<n and s[left] == s[right]:
res += 1
left -= 1
right += 1
return res
for i in range(n):
res = substrings(i,i,res)
res = substrings(i,i+1,res)
return res
打家劫舍
动态规划
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return nums[0]
if n == 2:
return max(nums[0],nums[1])
for i in range(2,n):
nums[i] = max(nums[0:i-1])+nums[i]
return max(nums[-1],nums[-2])
剑指 7.10—7.11
- 替换空格
- 斐波那契数列 (用递归会超时)
- 从尾到头打印链表(递归)
- 两个栈实现队列
- 二位数组中的查找(从右上角开始)
- 合并排序链表
- 第一次只出现一次的字符(用了一个函数 frequency = collections.Counter(s))
- 青蛙跳台阶(与斐波那契相同)
- 二进制中1的个数(n = n&(n-1))
- 数值的整数次方(降幂求,注意处理负指数与负底数)
- 无重复字符的最长子串
- 最小的k个数(小根堆,快排都要掌握)
- 旋转数组中的最小数字(二分,有点像找波峰那道题)
- 剪绳子1,2(尽可能的减去3,最后剩4不剪)
打印从1到n的最大数
其实是大数问题,数字的全排列,要变成字符串
class Solution:
def printNumbers(self, n: int) -> List[int]:
ans = []
s = ''
def dfs(index, s, digit):
if index == digit:
ans.append(int(s))
return
for i in range(10):
dfs(index + 1, s + str(i), digit)#用+就不需要pop啦
return ans
for digit in range(1, n + 1): # 几位数
for num in range(1, 10): # 固定首位
dfs(1, s + str(num), digit)
return ans
7.12
机器人的运动范围
回溯算法,从(0,0)开始往下跟右走进行,学到了一个nonlocal
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
ans = 0
def check(num):
res = 0
while num:
res += num % 10
num //= 10
return res
def enter(i, j, k,visited):
if i < 0 or i >= m or j < 0 or j >= n or check(i) + check(j) > k or visited[i][j] == 1:
return 0
nonlocal ans
ans += 1
visited[i][j] = 1
enter(i + 1, j, k, visited)
enter(i, j + 1, k, visited)
visited = [[0]*n for i in range(m)]
enter(0, 0, k, visited)
return ans
调整数组让所有偶数在奇数之前
解法:双指针
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
if not nums:
return []
n = len(nums)
left, right = 0, n-1
while left < right:
if nums[left] %2 != 0:
left += 1
elif nums[right] %2 == 0:
right -= 1
else:
nums[left], nums[right] = nums[right],nums[left]
left +=1
right -= 1
return nums
7.13
二叉树镜像
class Solution:
def mirrorTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
root.left, root.right = root.right,root.left
self.mirrorTree(root.left)
self.mirrorTree(root.right)
return root
对称二叉树
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root:
return True
def dfs(left,right):
#左右都空
if not (left or right):
return True
#左右有一个为空
if not (left and right):
return False
#左右不相等
if left.val!=right.val:
return False
return dfs(left.left,right.right) and dfs(left.right,right.left)
return dfs(root.left,root.right)
7.14
二叉树的层次遍历
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
if not root:
return []
ans = []
que = [root]
while que:
cur = que.pop(0)
ans.append(cur.val)
if cur.left:que.append(cur.left)
if cur.right:que.append(cur.right)
return ans
7.15
找到一个数组里不重复出现的两个数,异或
class Solution:
def singleNumbers(self, nums: List[int]) -> List[int]:
ans = functools.reduce(lambda x,y:x^y,nums)
div = 1
while ans & div == 0:
div <<= 1
a, b = 0, 0
for num in nums:
if num & div:
a = a^num
else:
b = b^num
return [a,b]
礼物的最大值
其实就是最大路径和,dp即可
class Solution:
def maxValue(self, grid: List[List[int]]) -> int:
if not grid:
return 0
dp = [float(-inf)] * (len(grid[0])+1)
dp[1] = 0
for row in grid:
for i,num in enumerate(row):
dp[i+1] = max(dp[i+1],dp[i])+num
return dp[-1]
7.21
中间隔了这么多天没刷题,我有罪,5555
矩阵中的路径,回溯
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
m = len(board)
n = len(board[0])
len_word = len(word)
if len_word > m * n :
return False
if len_word == 0:
return True
visited = [[0 for i in range(n)]for i in range(m)]
k = 0
def dfs(board,word,i,j,k,visited):
if i < 0 or i > m-1 or j <0 or j > n-1 or board[i][j]!=word[k] or visited[i][j] == 1:
return False
visited[i][j] = 1
if k == len_word -1:
return True
res = dfs(board,word,i+1,j,k+1,visited) or dfs(board,word,i-1,j,k+1,visited) or dfs(board,word,i,j-1,k+1,visited) or dfs(board,word,i,j+1,k+1,visited)
visited[i][j] = 0
return res
for i in range(m):
for j in range(n):
if dfs(board,word,i,j,k,visited):
return True
return False
7.22 股票的最大利润,设置一个变量记录最低价
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
maxPrice = float("-inf")
minPrice = float("inf")
for i in prices:
minPrice = min(minPrice,i)
maxPrice = max(maxPrice,i-minPrice)
return maxPrice
7.22 从上到下打印二叉树III
我是判断层数,反转数组
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
ans, que = [], collections.deque()
que.append(root)
level = 1
while que:
tmp = []
for i in range(len(que)):
cur = que.popleft()
tmp.append(cur.val)
if cur.left:que.append(cur.left)
if cur.right:que.append(cur.right)
ans.append(tmp) if level % 2 != 0 else ans.append(tmp[::-1])
level += 1
return ans
7.25 二叉树中和为一个值的路径
class Solution:
def pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
ans = []
if not root:
return []
def dfs(node,target,path):
if not node:return
path.append(node.val)
target -= node.val
if target == 0 and not node.left and not node.right:
ans.append(path[:])
path.pop()
return
dfs(node.left,target,path)
dfs(node.right,target,path)
path.pop()
dfs(root,target,[])
return ans
字符串的排列
class Solution:
def permutation(self, s: str) -> List[str]:
s = "".join((lambda x: (x.sort(), x)[1])(list(s)))
n = len(s)
num = ''
ans = []
def dfs(s,num,used):
if len(num) == n:
ans.append(num)
return
for i in range(n):
if i!= 0 and s[i] == s[i-1] and not used[i-1]:
continue
if not used[i]:
used[i] = 1
dfs(s,num+s[i],used)
used[i] = 0
used = [0 for _ in range(n)]
dfs(s,num,used)
return ans
7.28 构建乘积数组
用了dp,dp1先把该位数左边的×过来,每位对应原数组每位左边的乘积,dp2同理,是右边的乘积,两个数组按位×
class Solution:
def constructArr(self, a: List[int]) -> List[int]:
if not a:
return []
n = len(a)
dp = [0]*n
dp[0], dp[1] = 1, a[0]
for i in range(2,n):
dp[i] = dp[i-1]*a[i-1]
dp1 = [0]*n
dp1[n-1] = 1
for i in range(n-2,-1,-1):
dp1[i] = dp1[i+1]*a[i+1]
for i in range(n):
a[i] = dp[i]*dp1[i]
return a
7.29 复习了二叉树的三种遍历的递归与非递归方法,还有层次遍历,一共五题