Hot 100(三)
337. 打家劫舍 III
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:def __init__(self):self.memo = dict()def rob(self, root: Optional[TreeNode]) -> int:# # 暴力搜索 + 记忆化# if not root:# return 0# if self.memo.get(root):# return self.memo[root]# # 如果选择 root# res1 = root.val# if root.left:# res1 += self.rob(root.left.left) + self.rob(root.left.right)# if root.right:# res1 += self.rob(root.right.left) + self.rob(root.right.right)# # 如果不选择 root# res2 = self.rob(root.left) + self.rob(root.right)# res = max(res1, res2)# self.memo[root] = res# return res# 动态规划# f 表示选择节点 root 的情况下,所能获得的最大利益 f(root) = root.val + g(root.left) + g(root.right)# g 表示不选择节点 root 的情况下,所能获得的最大利益 g(root) = max(f(root.left), g(root.left)) + max(f(root.right), g(root.right))def DFS(root):if not root:return 0, 0# 后序遍历leftchild_steal, leftchild_nosteal = DFS(root.left)rightchild_steal, rightchild_nosteal = DFS(root.right)# 偷当前node,则最大收益为【投当前节点+不偷左右子树】steal = root.val + leftchild_nosteal + rightchild_nosteal# 不偷当前node,则可以偷左右子树nosteal = max(leftchild_steal, leftchild_nosteal) + max(rightchild_steal, rightchild_nosteal)return steal, nostealreturn max(DFS(root))
338. 比特位计数
class Solution:def countBits(self, n: int) -> List[int]:# 动态规划# 状态转移:奇数时,dp[i] = dp[i-1] + 1# 偶数时,dp[i] = dp[i // 2]res = [0 for _ in range(n+1)]for i in range(1, n+1):if i % 2 == 1:res[i] = res[i-1] + 1else:res[i] = res[i//2]return res
394. 字符串解码
class Solution:def decodeString(self, s: str) -> str:# 辅助栈stack, res, multi = [], "", 0for c in s:# 左括号时,重置 multi 和 res,multi 为要重复的次数,res 为待重复的字符串if c == '[':stack.append([multi, res])res, multi = "", 0# 右括号时,更新 reselif c == ']':cur_multi, last_res = stack.pop()res = last_res + cur_multi * reselif '0' <= c <= '9':multi = multi * 10 + int(c) else:res += creturn res
399. 除法求值
406. 根据身高重建队列
class Solution:def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:# 按照第一个元素降序排列,再按照第二个元素升序排列# 保证先放入 res 中的都是高个子res = []people = sorted(people, key = lambda x: (-x[0], x[1]))for p in people:if len(res) <= p[1]:res.append(p)else:res.insert(p[1], p)return res
416. 分割等和子集
class Solution:def canPartition(self, nums: List[int]) -> bool:# 动态规划# dp[i][j]表示 nums[:i+1]数组中是否可以选出和为 jn = len(nums)# 特殊情况处理if n < 2:return FalsenumsSum = sum(nums)maxNum = max(nums)# 和为奇数,无法选择if numsSum % 2 == 1:return False# 最大的数大于总和的一半,无法选择if 2 * maxNum > numsSum:return Falsetarget = numsSum // 2# dp数组和边界条件dp = [[False]*(target+1) for _ in range(n)]for i in range(n):dp[i][0] = Truedp[0][nums[0]] = Truefor i in range(1, n):num = nums[i]for j in range(1, target+1):if j >= num:# 可以选 num 或不选dp[i][j] = dp[i-1][j] or dp[i-1][j-num]else:# 不能选 numdp[i][j] = dp[i-1][j]return dp[n-1][target]# 空间可优化到一维,但需要注意从后往前更新,不然 dp[j-num]会被更新,不再是上一行的值
437. 路径总和 III
DFS or 前缀和
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:# DFS# 定义 rootSum(p, target) 表示以 p 为起点,且路径和为 target 的路径个数# 时间复杂度 O(n^2)def rootSum(p, target):if not p:return 0val = p.valres = 0# 这个不能直接 return,有负数if val == target:res += 1res += rootSum(p.left, target-val) + rootSum(p.right, target-val)return resif not root:return 0# 以根节点为起点的个数res = rootSum(root, targetSum)# 左子树的个数(不一定左节点是根节点)res += self.pathSum(root.left, targetSum)# 右子树的个数(不一定右节点是根节点)res += self.pathSum(root.right, targetSum)return res# # 前缀和# # 保存根节点到当前节点(不包括)的前缀和,当遍历到当前节点时,根节点到当前节点(包括)和为 curr,在前缀和 map 中查找是否存在和为 curr-target 的路径,则一定存在和为 target 的路径# prefix = collections.defaultdict(int)# prefix[0] = 1 # 空路径需要保存,处理 curr=target 的路径# # 返回 root 为根节点的和为 target 的路径条数,curr 为根节点到当前节点(不包括)和# def dfs(root, curr):# if not root:# return 0# ret = 0# curr += root.val # 根节点到当前节点(包括)和# ret += prefix[curr - targetSum] # 查找和为 curr-target 的路径个数# prefix[curr] += 1 # 更新前缀和# ret += dfs(root.left, curr)# ret += dfs(root.right, curr)# prefix[curr] -= 1 # 递归退出后需要删除,避免不是一条路径的# return ret# return dfs(root, 0)
Hot 100(三)相关推荐
- 数字电子技术课程设计之基于触发器的三位二进制同步减法计数器无效态000/110
基于触发器的三位二进制同步减法计数器无效态000/110 1 课程设计的目的与作用 掌握用multisim 的电路仿真程序 熟悉同步计数器工作原理和逻辑功能 熟悉计数器电路的分析和设计方法 掌握161 ...
- shell脚本之从1加到100之和的思路
一.使用双括号(())进行计算 #!/bin/bash # a=0 for((b=0;b<=100;b++));do((a=a+b)) //也可以写成a=$((a+b)) done echo $ ...
- linux 脚本1加到100,shell脚本之从1加到100之和的思路
一.使用双括号(())进行计算 #!/bin/bash # a=0 for((b=0;b<=100;b++));do ((a=a+b)) //也可以写成a=$((a+b)) done echo ...
- python面试文件操作_python基础-三分钟搞定面试官爱问的【文件操作】
一.使用python读写文本文件 使用Python来读或者写文本需要用到'open'这个关键字,它的作用是打开一个文件并创建一个文件对象. open语法结构: open(file, mode='r', ...
- python量化交易:Joinquant_量化交易基础【三】:python基本语法与变量
本文是量化交易零基础入门教程的第三篇. 摘要 python是什么 python的基础语法 变量与赋值 Python 保留字符 打印 print 全局变量 基本数据类型-数字与字符串 算术运算 查看数据 ...
- 年入100万是个梦,有3座大山需要翻越
雷观:文以载道,作而答题. 个税改革之后,税负终于有了一点实在的下降,2019年享受到了一点红利. 2020年,疫情之下,不少商家资金吃紧,没想到税务衙门也缺钱了. 个税需要自主申报,听说有人在讨论退 ...
- HTML(十二)三种常见布局:三栏式布局 双飞翼布局 圣杯布局
一.三栏式布局 顾名思义,即是将主页分成三部分(左,中,右),给左边和右边的块定宽,中间的块占据余下部分.以下是几种常用的实现方法 1.巧用浮动 优点:兼容性好,实现简单 缺点:必须先写浮动元素,再写 ...
- Python生成三年级数学竖式计算并用Python-pptx写入PPT
三年级下册的学生需要经常练习两位数乘两位数,三位数除以一位数的竖式计算,虽然出题难题简单,但是如果可以用程序一下生成,岂不是一劳永逸.那就动手吧. 首先需要安装Python-pptx,安装过程可能会因 ...
- 三、动画 -变形transform
目录: 1.变形transform定义 2.具体描述 3.用途 4.练习 一.变形transform定义 变形就是指通过CSS来改变元素的形状或位置 变形不会影响到页面的布局 transform 用来 ...
- 三小时学会css(菜鸟教程精华版)【下】
三小时学会css 上期传送门 CSS组合选择符 组合选择符说明了两个选择器直接的关系: 后代选择器(以空格 分隔) 子元素选择器(以大于 > 号分隔) 相邻兄弟选择器(以加号 + 分隔) 普通兄 ...
最新文章
- HDLBits 系列(5)让三元条件运算符(?:)在你的设计中发挥作用
- 深入MTK平台bootloader启动分析笔记
- Android fragmnet标签,在Android中为Fragment添加标签?
- itext pdf转图片_图片转PDF怎么转换?可以试试这个PDF转换软件
- uefi启动如何进入
- Kafka : kafka重启报错 ZkClient allready closed
- macOS Big Sur无法完成安装 Big Sur为什么安装不了?
- 基于体素的全局光照技术
- 【Redis】笔记(尚硅谷、黑马整合)
- 安卓 文本框怎么贴近边缘_【安卓,iOS】全网最火的充电提示音教程来啦
- 14443-A 与14443-B区别
- 2021全球程序员收入报告出炉!
- ZZNU2141: 2333
- Linux系统中OpenSSH的安装和配置(转)
- 扩充虚拟机文件系统的磁盘空间
- Vue 使用vue-seo-phantomjs 实现SEO抓取优化方案
- 关于Abaqus+python提取s11残余应力(按路径提取)
- 广州的11个辖区_对不起,你真的不了解广州11个区!
- 地图实现地点查找和导航
- 基于java的健身房会员管理系统