1512. 好数对的数目
没什么好说的,计数即可
class Solution:
def numIdenticalPairs(self, nums: List[int]) -> int:
cnt=collections.Counter(nums)
ans=0
for ni in cnt:
ans+=cnt[ni]*(cnt[ni]-1)//2
return ans
1513. 仅含 1 的子串数
滑动窗口,在每个全1的区间中含有1的子串数目为 f ( n ) = ∑ i = 1 n i = n ( n − 1 ) 2 f(n)=\sum_{i=1}^{n}i=\frac{n(n-1)}{2} f(n)=∑i=1ni=2n(n−1)
class Solution:
def numSub(self, s: str) -> int:
cnt=0
ans=0
for ch in s:
if ch=='1':
cnt+=1
else:
ans+=sum(range(cnt+1))
cnt=0
ans+=sum(range(cnt+1))
return ans%int(1e9+7)
1514. 概率最大的路径
dijkstra算法的变形,将权重最小改为概率最大,但是本质上还是可以通过优先队列实现
要注意的是,python内置的heap包使用的是小顶堆,使用的时候注意改成大顶堆(存入负值即可)
class Solution:
def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
#初始化邻接表
glpyh=collections.defaultdict(list)
probdict=collections.defaultdict(dict)
for i,(a,b) in enumerate(edges):
glpyh[a].append(b)
glpyh[b].append(a)
probdict[a][b]=probdict[b][a]=succProb[i]
#
memo=collections.defaultdict(int)
memo[start]=1
#建堆 因为初始只有一个start所以不需要初始化堆
heap=[(-1,start)]
while heap:
curprob,cur=heapq.heappop(heap)
curprob*=-1
for nxt in glpyh[cur]:
# 没有确定的再进队列
if probdict[cur][nxt]*curprob > memo[nxt]:
memo[nxt]=probdict[cur][nxt]*curprob
heapq.heappush(heap,(-probdict[cur][nxt]*curprob,nxt))
return memo[end]
1515. 服务中心的最佳位置
频道里有大佬指出这是机器学习的算法,但是这题不应该直接用计算物理的方法解决么,计算物理里的求解势能最低点的matlab文件我还留着呢。
基本思路就是沿着梯度的方向函数值下降最快,通过检查每次迭代后的新值与旧值之差作为迭代结束的标志,算法可视化如下。
class Solution:
def getMinDistSum(self, positions: List[List[int]]) -> float:
if len(positions)==1:
return 0
#求势能
def getpotential(token):
return sum( ( ( token[0]-x) **2 + ( token[1]-y) **2 )**0.5 for x,y in positions )
#求梯度
def getgrad(token):
r=[ (( token[0]-x) **2 + ( token[1]-y) **2 )**0.5 for x,y in positions ]
res=[0,0]
for i,(x,y) in enumerate(positions):
res[0]+=( token[0] - x)/r[i]
res[1]+=( token[1] - y)/r[i]
return res
token=[1.5,1.5]
p1=getpotential(token)
theta=0.03#步长,每步走多少
eps=1e-8
while True:
grad=getgrad(token)
newtoken=[token[0]-theta*grad[0],token[1]-theta*grad[1]]
newp=getpotential(newtoken)
#值减少 继续迭代
if p1-newp>eps:
p1=newp
token=newtoken
#说明这一步走的有点大,调整步长
elif newp-p1>eps:
theta/=3
#已经到达终点,返回所求
else:
return p1