337-打家劫舍3(python)
#完全背包0/1
class Solution:
def rob(self,root):
def robinterger(root):
res=[0,0]
if not root:return res
left=robinterger(root.left)
right=robinterger(root.right)
res[0]+=max(left[0],left[1])+max(right[0],right[1])
res[1]+=root.val+left[0]+right[0]
robinterger(root)
return res
338-比特位计数(python)
#动态规划
class Solution:
def countBits(self, num: int) -> List[int]:
dp=[0]*(num+1)
for i in range(1,num+1):
if(i%2==1):
dp[i]=dp[i-1]+1
else:
dp[i]=dp[i//2]
return dp
347-前k个高频元素(python)
#dict
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
dict={}
for num in nums:
dict[num]=dict.get(num,0)+1
dict=sorted(dict,key=dict.__getitem__,reverse=True)
return dict[0:k]
581-最短无序连续子数组(python)
#找左右区间
class Solution:
def findUnsortedArray(self,nums):
n=len(nums)
max_num=nums[0]
right=0
for i in range(n):
if nums[i]>=max_num:
max_num=nums[i]
else:
right=i
min_num=nums[n-1]
left=n-1
for j in range(n-1,-1,-1):
if nums[i]<=min_num:
min_num=nums[i]
else:
left=j
return right-left+1 if (right-left+1)>0 else 0
560-和为k的子数组(python)
#hash
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
hash={0:1}
sum=0
count=0
for i in range(len(nums)):
sum+=nums[i]
if((sum-k) in hash):
count+=hash[sum-k]
if(sum in hash):
hash[sum]+=1
else:
hash[sum]=1
return count
543-二叉树的直径(python)
class Solution(object):
def diameterOfBinaryTree(self, root):
self.ans=1
def depth(node):
if not node: return 0
L = depth(node.left)
R = depth(node.right)
self.ans = max(self.ans, L+R+1)
return max(L, R) + 1
depth(root)
return self.ans - 1
337-打家劫舍3(python)
#深度优先 递归算法:先遍历右节点,再存储根节点,最后遍历左节点
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
self.sum = 0
def dfs(root):
if not root: return root
dfs(root.right)
self.sum = self.sum + root.val
root.val = self.sum
dfs(root.left)
return root
return dfs(root)
647-回文子串(python)
#中心扩展法
class Solution(object):
def countSubstrings(self, s):
def get_Center(s,l,r):
count = 0
while l>=0 and r<len(s) and s[l]==s[r]:
l-=1
r+=1
count+=1
return count
n = len(s)
sum1 = 0
for i in range(len(s)):
count_even = get_Center(s,i,i)
count_odd = get_Center(s,i,i+1)
sum1 = sum1+count_even+count_odd
return sum1
416-分割和子集(python)-给一数组分为等值的两个子集
#动态规划
class Solution:
def canPartition(self, nums: List[int]) -> bool:
n=len(nums)
target=sum(nums)
if(target%2!=0):
return False
target//=2
dp=[[False]*(target+1) for _ in range(n)]
dp[0][0]=True
for i in range(1,target+1):
if(nums[0]==i):
dp[0][i]=True
break
for i in range(1,n):
for j in range(target+1):
if(j>=nums[i]):
dp[i][j]=dp[i-1][j] or (dp[i-1][j-nums[i]])
else:
dp[i][j]=dp[i-1][j]
return dp[-1][-1]
406-根据身高重建队列(python)
#先按身高降序排列,然后按照k值插入排序
class Solution(object):
def reconstructQueue(self, people):
people.sort(key=lambda (h, k): (-h, k))
res=[]
for p in people:
res.insert(p[1],p)
return res
494-目标和(python)
#转换为求数组中子集满足正数V
class Solution:
def findTargetSumWays(self, nums: List[int], S: int) -> int:
if (sum(nums)+S)%2!=0 or sum(nums)<S:
return 0
V=(sum(nums)+S)//2
dp=[0]*(V+1)
dp[0]=1
for num in nums:
i=V
while i>=num:
dp[i]+=dp[i-num]
i-=1
return dp[-1]
448-找到数组中消失的数字(python)
#将不等于i+1的index值放在其正确位置上
class Solution:
def findDisappearNumbers(self,num):
res=[]
for i in range(len(nums):
while nums[i]!=i+1 and nums[i]!=nums[nums[i]-1]:
nums[i],nums[nums[i]-1]=nums[nums[i]-1],nums[i]
for i in range(len(nums)):
if nums[i]!=i+1:
res.append(i+1)
return res
437-路径总和3(python)
class Solution(object):
def pathSum(self, root, sum):
if not root:
return 0
# target 所有路径所能构成的和列表
def dfs(node, target):
if not node:
return 0
# 左右的值默认为0
l, r = 0, 0
# 之前的和依次加上当前节点的值,再添加当前节点
target = [node.val] + [_ + node.val for _ in target]
# 递归
l = dfs(node.left, target)
r = dfs(node.right, target)
# 计算当前的路径和等于给定数值的个数
return target.count(sum) + l + r
return dfs(root, [])
438-找到字符串中所有字母异味词(python)
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
res=[]
window={}
needs={}
for c in p:needs[c]=needs.get(c,0)+1
left=right=0
while right<len(s):
c=s[right]
if c not in needs:
window.clear()
left=right=right+1
else:
window[c]=window.get(c,0)+1
if right-left+1==len(p):
if window==needs:
res.append(left)
window[s[left]]-=1
left+=1
right+=1
return res
309-最佳股票买卖时机(python)
#动态规划
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices: return 0
l = len(prices)
dp = [[0, 0] for _ in range(l+1)]
dp[0][1] = float('-inf')
dp[1][1] = -prices[0]
for i in range(2, l+1): # 因为下面有i-2所以从2开始, 自行去填0-1的base case
dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i-1])
dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i-1])
return dp[-1][0]
312-戳气球(python)
#动态规划
class Solution:
def maxCoins(self, nums: List[int]) -> int:
nums = [1]+nums+[1]
l = len(nums)
# print(nums)
dp = [[0]*l for _ in range(l)] # dp[i][j]为[i,j]之间的最大值, 注意这里不能选i或j去戳破, 否则子问题会有重叠
for i in range(l-3, -1, -1): # 这点是从后往前! 要使小范围的[i,j]先被计算!!
for j in range(i+2, l):
for k in range(i+1, j):
dp[i][j] = max(dp[i][j], dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j])
return dp[0][-1]
394-字符串解码(python)
class Solution:
def decodeString(self, s: str) -> str:
stack, res, multi = [], "", 0
for c in s:
if c == '[':
stack.append([multi, res])
res, multi = "", 0
elif c == ']':
cur_multi, last_res = stack.pop()
res = last_res + cur_multi * res
elif '0' <= c <= '9':
multi = multi * 10 + int(c)
else:
res += c
return res