记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
6/20 715. Range 模块
线段树 动态开点+懒标记
v代表是添加或者删除 val表示当前点是否在区间内
MAXNUM = int(1e9+7)
class Node:
def __init__(self):
self.left = None
self.right = None
self.val = False
self.add = False
class RangeModule(object):
def __init__(self):
self.root = Node()
def update(self,node,lc,rc,l,r,v):
if l<=lc and r>=rc:
node.val = v
node.add = True
return
self.pushdown(node)
mid = (lc+rc)>>1
if l<=mid:
self.update(node.left,lc,mid,l,r,v)
if r>mid:
self.update(node.right,mid+1,rc,l,r,v)
self.pushup(node)
def query(self,node,lc,rc,l,r):
if l<=lc and r>=rc:
return node.val
self.pushdown(node)
mid = (lc+rc)>>1
ans = True
if l<=mid:
ans = ans and self.query(node.left,lc,mid,l,r)
if r>mid:
ans = ans and self.query(node.right,mid+1,rc,l,r)
return ans
def pushdown(self,node):
if not node.left :
node.left = Node()
if not node.right:
node.right = Node()
if not node.add:
return
node.left.val = node.val
node.right.val = node.val
node.left.add = True
node.right.add = True
node.add = False
def pushup(self,node):
node.val = node.left.val and node.right.val
def addRange(self, left, right):
"""
:type left: int
:type right: int
:rtype: None
"""
self.update(self.root,1,MAXNUM,left,right-1,True)
def queryRange(self, left, right):
"""
:type left: int
:type right: int
:rtype: bool
"""
return self.query(self.root,1,MAXNUM,left,right-1)
def removeRange(self, left, right):
"""
:type left: int
:type right: int
:rtype: None
"""
self.update(self.root,1,MAXNUM,left,right-1,False)
6/21 1108. IP 地址无效化
根据.切割字符串 加入[.]
def defangIPaddr(address):
"""
:type address: str
:rtype: str
"""
return "[.]".join(address.split("."))
6/22 513. 找树左下角的值
dfs深搜
find 返回当前节点为根节点的子树 最深深度及最左边的值
def findBottomLeftValue(root):
"""
:type root: TreeNode
:rtype: int
"""
def find(node,deep):
val,dep = node.val,deep
valr,depr = node.val,deep
if node.left:
val,dep = find(node.left,deep+1)
if node.right:
valr,depr = find(node.right,deep+1)
if depr>dep:
val,dep = valr,depr
return val,dep
val,_=find(root,0)
return val
6/23 30. 串联所有单词的子串
每个单词长度一致=n
从0~n-1位置开始分别考虑
m为需要出现的单词数量
间隔n为一个单词 滑动窗口记录出现单词数目
每一次右侧位置向右取一个单词
如果出现不存在单词
则将整个窗口移到这个单词右侧重新开始计算
如果所有需要出现的单词都已经出现
则记录当前起始位置
将左侧窗口向右移动一个单词继续考虑
def findSubstring(s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
n = len(words[0])
m = {}
for word in words:
m[word] = m.get(word,0)+1
num = len(words)
ans = []
for i in range(n):
left = i
right = i
tmpm = m.copy()
while right+n<=len(s):
word = s[right:right+n]
if word not in m:
left = right +n
right = left
tmpm = m.copy()
else:
tmpm[word]-=1
right += n
if right - left == num*n:
if all([v==0 for v in tmpm.values()]):
ans.append(left)
word = s[left:left+n]
left = left+n
tmpm[word] +=1
return ans
6/24 515. 在每个树行中找最大值
BFS 广搜每一层 记录最大值
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def largestValues(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ans = []
l = [root]
while l:
tmp = []
val = 0
for node in l:
val = max(val,node.val)
if node.left:
tmp.append(node.left)
if node.right:
tmp.append(node.right)
ans.append(val)
l = tmp
return ans
6/25 剑指 Offer II 091. 粉刷房子
动态规划
r[x],b[x],g[x]分别代表从起始开始到当前房子x,x被刷成红色/蓝色/绿色时最小的话费
r[x] = min(b[x-1],g[x-1])+cost[x][red]
其他亦然
最终比较最后位置三个结果取最小即可
def minCost(costs):
"""
:type costs: List[List[int]]
:rtype: int
"""
r,b,g = costs[0][0],costs[0][1],costs[0][2]
for cr,cb,cg in costs[1:]:
r,b,g = min(b,g)+cr,min(r,g)+cb,min(r,b)+cg
return min(r,b,g)
6/26 710. 黑名单中的随机数
能够随机到的数 一共有n-len(blacklist)个
在这个范围内随机
这个范围内的黑名单的数
与剩余的len(blacklist)个数中的可随机数映射
import random
class Solution(object):
def __init__(self, n, blacklist):
"""
:type n: int
:type blacklist: List[int]
"""
self.s = n-len(blacklist)
self.m = {}
b = set(blacklist)
start = self.s-1
for i in blacklist:
if i<self.s:
start +=1
while start in b:
start+=1
self.m[i] = start
def pick(self):
"""
:rtype: int
"""
rd = random.randint(0,self.s-1)
if rd in self.m:
rd = self.m[rd]
return rd