记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
12/12 1781. 所有子字符串美丽值之和
遍历每一个子串 记录字串中每种字符的出现次数
def beautySum(s):
"""
:type s: str
:rtype: int
"""
from collections import defaultdict
n = len(s)
ans = 0
for i in range(n-1):
m = defaultdict(int)
m[s[i]]=1
for j in range(i+1,n):
m[s[j]]+=1
ans += max(m.values())-min(m.values())
return ans
12/13 1832. 判断句子是否为全字母句
长度小于26必定不行 遍历 存入map 最后判断map长度
def checkIfPangram(sentence):
"""
:type sentence: str
:rtype: bool
"""
n = len(sentence)
if n<26:
return False
m = {}
for c in sentence:
m[c]=1
return True if len(m)==26 else False
12/14 1697. 检查边长度限制的路径是否存在
并查集
对于某个查询p,q,limit
遍历所有边将小于limit的都加入到并查集中
最后如果p,q在同个集合说明可以走到
将查询limit从小到大排序可以重复使用并查集
def distanceLimitedPathsExist(n, edgeList, queries):
"""
:type n: int
:type edgeList: List[List[int]]
:type queries: List[List[int]]
:rtype: List[bool]
"""
edgeList.sort(key=lambda x:x[2])
un = list(range(n))
def find(x):
if un[x]!=x:
un[x] = find(un[x])
return un[x]
def merge(a,b):
un[find(a)]=find(b)
ans = [False]*len(queries)
ind = 0
for i,(p,q,limit) in sorted(enumerate(queries),key = lambda x:x[1][2]):
while ind < len(edgeList) and edgeList[ind][2]<limit:
merge(edgeList[ind][1],edgeList[ind][0])
ind+=1
ans[i] = find(p)==find(q)
return ans
12/15 1945. 字符串转化后的各位数字之和
第一次必定是字母转数字
后续继续k次
def getLucky(s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
st = ""
for c in s:
v = ord(c)-ord("a")+1
st += str(v)
ans = int(st)
for _ in range(k):
tmp = 0
while ans >0:
tmp += ans%10
ans //=10
ans = tmp
if ans<10:
break
return ans
12/16 1785. 构成特定和需要添加的最少元素
求和 与goal之间差值target 取绝对值后 需要多少个limit
def minElements(nums, limit, goal):
"""
:type nums: List[int]
:type limit: int
:type goal: int
:rtype: int
"""
s = sum(nums)
target = abs(goal-s)
ans = target//limit
if target%limit>0:
ans +=1
return ans
12/17 1764. 通过连接另一个数组的子数组得到一个数组
从头遍历groups内整数 和nums内整数是否能一一对应
nums内需要连续的子数组对应
def canChoose(groups, nums):
"""
:type groups: List[List[int]]
:type nums: List[int]
:rtype: bool
"""
n = len(nums)
loc = 0
for i,g in enumerate(groups):
m = len(g)
tag = False
while loc<n and loc+m<=n:
if nums[loc]==g[0]:
if nums[loc:loc+m]==g:
loc = loc+m
tag = True
if i==len(groups)-1:
return True
break
else:
loc+=1
else:
loc+=1
if not tag:
return False
return False
12/18 1703. 得到连续 K 个 1 的最少相邻交换次数
将k个1挪到一起 为了交换次数最少
这k个1在之前必定也是连续的
假设第i个1为qi q0移动到x q1移动到x+1 q2移动到x+2
=>q0->x q1-1->x q2-2->x
设pi=qi-i 计算pi到x的距离和最小值 x为pi中位数为最右p(k/2)
g[i]为第i个1与前一个1之间0的数目
设s为p的前缀和 距离和为s0+sk-2s(k/2)-p(k/2)(k%2)
枚举第i个1 是结果中最左边的1
def minMoves(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
g = []
pre = [0]
for i,num in enumerate(nums):
if num==1:
g.append(i-len(g))
pre.append(pre[-1]+g[-1])
n = len(g)
if n==len(nums):
return 0
ans = float('inf')
for i in range(n-k+1):
sl = pre[i]
sm = pre[i+k//2]
sr = pre[i+k]
ans = min(ans,sl+sr-2*sm - g[i+k//2]*(k%2))
return ans