Leetcode 周赛 197

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(n1)

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值