记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
5/30 1022. 从根到叶的二进制数之和
dfs 根节点能得到的值为左右子节点能得到值的和
如果为叶子节点则返回其值 若为空则返回0
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def sumRootToLeaf(root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(node,cur):
if not node:
return 0
cur = (cur<<1) + node.val
if (not node.left) and (not node.right):
return cur
return dfs(node.left,cur)+dfs(node.right,cur)
return dfs(root,0)
5/31 剑指 Offer II 114. 外星文字典
拓扑排序
out[c]记录比字母c排序靠后的字母有哪些
inNum[c]记录字母c入度 即当前比字母c排序靠前未被处理的字母个数
依次遍历所有相邻的单词
将所有出现过的字母入度初始化为0
如果后一个单词为前一个单词的前缀 则不存在合法顺序
两个单词w1,w2出现首个位置字母不同时 u,v 可以得到u比v字典序小
则将v加入到out[u]中
并且v的入度+1 inNum[v]+=1
处理完后 可将入度为0的字母加入到序列l中
遍历序列l中的字母c 将字母c出的字母v 入度-1 如果入度变为0
则可以加入到l中
最后判断出现过的字母是否都在l中
如果缺失则说明有环 不存在合法顺序
def alienOrder(words):
"""
:type words: List[str]
:rtype: str
"""
from collections import defaultdict
out = defaultdict(list)
inNum = {c:0 for c in words[0]}
for i in range(1,len(words)):
w1,w2 = words[i-1],words[i]
if len(w1)>len(w2) and w1[:len(w2)]==w2:
return ""
for c in w2:
inNum[c] = inNum.get(c,0)
for u,v in zip(w1,w2):
if u!=v:
out[u].append(v)
inNum[v] +=1
break
l = []
for c in inNum:
if inNum[c]==0:
l.append(c)
for c in l:
for v in out[c]:
inNum[v]-=1
if inNum[v]==0:
l.append(v)
if len(l)==len(inNum):
return "".join(l)
return ""
6/1 473. 火柴拼正方形
先求总和 如果不是4的倍数则返回失败
将火柴从大到小排序 回溯
求出正方形每条边长l
将火柴依次放入每条边中 dfs 如果成功凑成边长l 返回成功
否则 取出火柴放入下一条边
def makesquare(matchsticks):
"""
:type matchsticks: List[int]
:rtype: bool
"""
matchsticks.sort(reverse=True)
total = sum(matchsticks)
if total%4>0:
return False
l = total // 4
li = [l]*4
if matchsticks[0]>l:
return False
def dfs(loc):
if loc==len(matchsticks):
return True
for i in range(4):
li[i]-=matchsticks[loc]
if li[i]>=0 and dfs(loc+1):
return True
li[i]+=matchsticks[loc]
return False
return dfs(0)
6/2 450. 删除二叉搜索树中的节点
寻找到key值的node 记录父节点par
在左子树中找到最大值或者 在右子树中找到最小值替换node的值
如果node是叶子节点 则父节点连接node的子树为空
特殊处理不包含节点 以及仅有一个key值节点
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def deleteNode(root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
node = root
par = root
if not root:
return None
if root.val == key and (not root.left) and (not root.right):
return None
while node.val!=key:
par = node
if node.left and key<node.val:
node = node.left
continue
if node.right and key>node.val:
node = node.right
continue
return root
if node.left:
pre = node
tmp = node.left
while tmp.right:
pre = tmp
tmp = tmp.right
node.val = tmp.val
if node.left.right:
pre.right = tmp.left
else:
pre.left = tmp.left
elif node.right:
pre = node
tmp = node.right
while tmp.left:
pre = tmp
tmp = tmp.left
node.val = tmp.val
if node.right.left:
pre.left = tmp.right
else:
pre.right = tmp.right
else:
if par.left == node:
par.left = None
else:
par.right = None
return root
6/3 829. 连续整数求和
n是否可以表示成k个连续整数之和
如果k是奇数 且n能被k整除 则可以
如果k是偶数 且n不能被k整除 且2n可以被k整除时 可以
def consecutiveNumbersSum(n):
"""
:type n: int
:rtype: int
"""
def find(k):
if k%2==1:
return n%k==0
return n%k and 2*n%k==0
ans = 0
k = 1
while k*(k+1)<=2*n:
if find(k):
print(k)
ans +=1
k+=1
return ans
6/4 929. 独特的电子邮件地址
哈希表m记录不一样的地址
将本地名处理后记录结果目标地址
def numUniqueEmails(emails):
"""
:type emails: List[str]
:rtype: int
"""
m = {}
for email in emails:
l = email.split('@')
loc = l[0]
loc = loc.split('+')[0]
loc = loc.replace('.','')
m[loc+"@"+l[1]] = 1
return len(m)
6/5 478. 在圆内随机生成点
对于半径为r的圆 随机在[-r,r]的正方形中取点(x,y)
如果x,y在圆内即可 圆内每个点出现的概率相同
class Solution(object):
def __init__(self, radius, x_center, y_center):
"""
:type radius: float
:type x_center: float
:type y_center: float
"""
self.xc = x_center
self.yc = y_center
self.r = radius
def randPoint(self):
"""
:rtype: List[float]
"""
import random
while True:
x,y = random.uniform(-self.r,self.r),random.uniform(-self.r,self.r)
if x*x+y*y<=self.r*self.r:
return [self.xc+x,self.yc+y]