记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
3/14 599. 两个列表的最小索引总和
遍历第一个列表记录所有值所对应索引
遍历第二个列表如果所对应的值存在第一个列表 计算索引和 判断是否最小
def findRestaurant(list1, list2):
"""
:type list1: List[str]
:type list2: List[str]
:rtype: List[str]
"""
m = {}
for loc,v in enumerate(list1):
m[v] = loc
num = float("inf")
ans = []
for loc,v in enumerate(list2):
if v in m:
if num>m[v]+loc:
ans = [v]
num = m[v]+loc
elif num == m[v]+loc:
ans.append(v)
return ans
3/15 2044. 统计按位或能得到最大值的子集数目
所有数都按位或必定是最大
n位数一共有2^n种可能 用一个n为二进制表示选择的数
如果得到目标值 结果+1
def countMaxOrSubsets(nums):
"""
:type nums: List[int]
:rtype: int
"""
target = 0
for num in nums:
target |=num
n = len(nums)
ans = 0
for i in range(1,2**n):
v = 0
for loc in range(n):
if i&(1<<loc)>0:
v |=nums[loc]
if v==target:
ans +=1
return ans
3/16 432. 全 O(1) 的数据结构
双向链表node 每个节点记录出现不同次数的keys
按照出现次数从小到大排列
nodes[key]哈希表记录字符串key所在节点
添加key时:
判断key是否已经存在
如果不存在:
判断是把key加入到出现次数1的node中
还是新建一个出现次数为1的node
如果存在:
判断key出现次数cnt+1的node是否存在 把key加入
或者新建一个cnt+1的node
把key从原来的node中移除
如果原来node没有key则将node移除
减去key时:
如果nodes[key] key只出现过一次
则移除key
否则判断cnt-1的node是否存在 将key将入或者新建node
出现次数最少的就是root之后第一个node中的keys
出现最多的就是root之前 最后一个node中的keys
class Node(object):
def __init__(self,key="",cnt=0):
self.prev = None
self.next = None
self.keys = set([key])
self.cnt = cnt
def insert(self,node):
node.prev = self
node.next = self.next
node.prev.next = node
node.next.prev = node
return node
def remove(self):
self.prev.next = self.next
self.next.prev = self.prev
class AllOne(object):
def __init__(self):
self.nodes = {}
self.root = Node()
self.root.prev = self.root
self.root.next = self.root
def inc(self, key):
"""
:type key: str
:rtype: None
"""
if key not in self.nodes:
if self.root.next == self.root or self.root.next.cnt>1:
node = self.root.insert(Node(key,1))
self.nodes[key] = node
else:
self.root.next.keys.add(key)
self.nodes[key] = self.root.next
else:
node = self.nodes[key]
nxt = node.next
if nxt == self.root or nxt.cnt>node.cnt+1:
self.nodes[key] = node.insert(Node(key,node.cnt+1))
else:
nxt.keys.add(key)
self.nodes[key] = nxt
node.keys.remove(key)
if len(node.keys)==0:
node.remove()
def dec(self, key):
"""
:type key: str
:rtype: None
"""
node = self.nodes[key]
if node.cnt==1:
del self.nodes[key]
else:
pre = node.prev
if pre==self.root or pre.cnt<node.cnt-1:
self.nodes[key] = node.prev.insert(Node(key,node.cnt-1))
else:
pre.keys.add(key)
self.nodes[key] = pre
node.keys.remove(key)
if len(node.keys)==0:
node.remove()
def getMaxKey(self):
"""
:rtype: str
"""
if self.root.prev==self.root:
return ""
else:
v = self.root.prev.keys.pop()
self.root.prev.keys.add(v)
return v
def getMinKey(self):
"""
:rtype: str
"""
if self.root.next==self.root:
return ""
else:
v = self.root.next.keys.pop()
self.root.next.keys.add(v)
return v
3/17 720. 词典中最长的单词
1.对列表从短到长排序 使用字典树
对于单词word如果能够找到word[:-1]之前的字符串 则可以将word加入字典中
记录最长单词
2.对列表从短到长排序
使用set保存满足条件的单词
def longestWord(words):
"""
:type words: List[str]
:rtype: str
"""
words.sort(key=lambda x:len(x))
from collections import defaultdict
dic = defaultdict(map)
ans = ""
num = 0
for word in words:
if len(word)==1:
dic[word]={}
if num<1 or (num==1 and word<ans):
num=1
ans = word
else:
tmpdic = dic
tag = True
for c in word[:-1]:
if c in tmpdic:
tmpdic = tmpdic[c]
else:
tag = False
break
if tag:
tmpdic[word[-1]]={}
if num<len(word) or (num==len(word) and word<ans):
num = len(word)
ans = word
return ans
def longestWord2(words):
"""
:type words: List[str]
:rtype: str
"""
value = set([""])
for word in sorted(words):
if word[:-1] in value:
value.add(word)
return max(sorted(value),key=len)
3/18 2043. 简易银行系统
模拟
class Bank(object):
def __init__(self, balance):
"""
:type balance: List[int]
"""
self.num = len(balance)
self.bl = balance
def transfer(self, account1, account2, money):
"""
:type account1: int
:type account2: int
:type money: int
:rtype: bool
"""
if max(account1,account2)>self.num or self.bl[account1-1]<money:
return False
self.bl[account1-1]-=money
self.bl[account2-1]+=money
return True
def deposit(self, account, money):
"""
:type account: int
:type money: int
:rtype: bool
"""
if account>self.num:
return False
self.bl[account-1]+=money
return True
def withdraw(self, account, money):
"""
:type account: int
:type money: int
:rtype: bool
"""
if account>self.num or self.bl[account-1]<money:
return False
self.bl[account-1]-=money
return True
3/19 606. 根据二叉树创建字符串
递归 左子节点为空需要加空括号 右子节点为空不需要加
根左右
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def tree2str(root):
"""
:type root: TreeNode
:rtype: str
"""
def find(node):
if not node:
return ""
if not node.left and not node.right:
return str(node.val)
if not node.right:
return "%d(%s)"%(node.val,find(node.left))
return "%d(%s)(%s)"%(node.val,find(node.left),find(node.right))
return find(root)
3/20 2039. 网络空闲的时刻
利用广搜先求出各个节点到0服务器的最短路径dist
消息x从节点到0服务器再返回需要2dist
节点每p[x]发送一次信息
如果p[x]>=2dist 第二次信息不会发出
如果p[x]<2dist 会发送多次信息
最后一次信息发送为p[x]((2dist-1)//p[x])
最后需要2dist返回 1秒后空闲
def networkBecomesIdle(edges, patience):
"""
:type edges: List[List[int]]
:type patience: List[int]
:rtype: int
"""
n = len(patience)
m = [[] for _ in range(n)]
for x,y in edges:
m[x].append(y)
m[y].append(x)
mem = [False]*n
mem[0] = True
l = [0]
ans,dist = 0,1
while l:
tmp = []
for loc in l:
for node in m[loc]:
if mem[node]:
continue
mem[node] = True
tmp.append(node)
ans = max(ans,(dist*2-1)//patience[node]*patience[node]+2*dist+1)
l = tmp
dist +=1
return ans