记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
一次遍历 如果无法击败则增加训练时间
def minNumberOfHours(initialEnergy, initialExperience, energy, experience):
"""
:type initialEnergy: int
:type initialExperience: int
:type energy: List[int]
:type experience: List[int]
:rtype: int
"""
ans = 0
curen,curex = initialEnergy,initialExperience
for i in range(len(energy)):
print(i,ans,curen,curex)
if curex<=experience[i]:
ans += experience[i]+1-curex
curex = experience[i]+1
curex += experience[i]
curen -= energy[i]
if curen<=0:
ans =ans - curen+1
curen=1
return ans
既然必定存在一个答案 各行和总数=各列和总数
目的是找到分配数值的方案
根据n,m = len(rowSum),len(colSum)
我们可以知道答案是一个n*m的矩阵
1.可以先将列之和分配到第一行的各列之中
例:rowSum = [5,7,10], colSum = [8,6,8]
8,6,8
0,0,0
0,0,0
此后数值的增减操作只在同一列中进行
所以每列之和已经满足条件不需要再考虑
2.依次根据rowSum 通过减去数值来使该行和满足条件
减去的数值增加到该列中的下一行中(列之和不变)
处理第一行
5,0,0
3,6,8
0,0,0
处理第二行
5,0,0
3,4,0
0,2,8
此时第三行自动满足条件
def restoreMatrix(rowSum, colSum):
"""
:type rowSum: List[int]
:type colSum: List[int]
:rtype: List[List[int]]
"""
n,m = len(rowSum),len(colSum)
ans = [[0]*m for _ in range(n)]
ans[0] = colSum[:]
for i in range(n-1):
target = rowSum[i]
for j in range(m):
if target>=ans[i][j]:
target-=ans[i][j]
else:
tmp = ans[i][j]
ans[i][j] = target
ans[i+1][j] = tmp-target
target = 0
return ans
遍历所有路 记录每个节点拥有的道路 以及其连接的其他节点
选取两两节点 计算其拥有的秩
def maximalNetworkRank(n, roads):
"""
:type n: int
:type roads: List[List[int]]
:rtype: int
"""
from collections import defaultdict
way = defaultdict(int)
nxt = defaultdict(set)
for i,j in roads:
way[i]+=1
way[j]+=1
nxt[i].add(j)
nxt[j].add(i)
ans = 0
for i in range(n-1):
for j in range(i+1,n):
tmp = way[i]+way[j]
if j in nxt[i]:
tmp-=1
ans = max(ans,tmp)
return ans
根据题意k是必须选择的
找到k的位置
该位置标签设定为0
分别向左右判断标签 比k大的+1 比k小的-1
记录左右各个位置标签状态
从左右分别选取一个位置标签 使其相加等于0或1 可以满足条件
def countSubarrays(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
from collections import defaultdict
n = len(nums)
ind = 0
left,right=defaultdict(int),defaultdict(int)
for i in range(n):
if nums[i]==k:
ind=i
break
cur = 0
for i in range(ind+1,n):
if nums[i]<k:
cur-=1
else:
cur+=1
right[cur]+=1
cur = 0
for i in range(ind-1,-1,-1):
if nums[i]<k:
cur-=1
else:
cur+=1
left[cur]+=1
ans = 1+left[0]+right[0]+left[1]+right[1]
if len(left)<len(right):
for k,v in left.items():
ans += v*right[0-k]
ans += v*right[1-k]
else:
for k,v in right.items():
ans += v*left[0-k]
ans += v*left[1-k]
return ans
排序后 前缀和
从前缀和序列中寻找
def answerQueries(nums, queries):
"""
:type nums: List[int]
:type queries: List[int]
:rtype: List[int]
"""
from itertools import accumulate
import bisect
nums.sort()
s = list(accumulate(nums))
return [bisect.bisect_right(s, q) for q in queries]
长度为n
双指针i,j 一个从a头部开始 一个从b尾部开始
两指针同时向中间移动 直到i,j交叉i>=j 或者遇到不同字符
def checkPalindromeFormation(a, b):
"""
:type a: str
:type b: str
:rtype: bool
"""
n = len(a)
def check(a,b):
i,j=0,n-1
while i<j and a[i]==b[j]:
i +=1
j -=1
return i>=j or a[i:j+1]==a[i:j+1][::-1] or b[i:j+1]==b[i:j+1][::-1]
return check(a,b) or check(b,a)
广搜 遍历所有可能
def findLexSmallestString(s, a, b):
"""
:type s: str
:type a: int
:type b: int
:rtype: str
"""
l = [s]
mem = {s}
ans = s
while l:
tmp = []
for v in l:
if ans>v:
ans = v
s1 = v[-b:]+v[:-b]
s2 = ''.join([str((int(c)+a)%10) if i&1 else c for i,c in enumerate(v)])
for t in (s1,s2):
if t not in mem:
mem.add(t)
tmp.append(t)
l = tmp[:]
return ans