记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
分解 排序
找到最先不同的位置
def maximumSwap(num):
"""
:type num: int
:rtype: int
"""
l = []
ori = num
while num>0:
l.append(num%10)
num//=10
n = len(l)
tmp = [v for v in l]
tmp.sort()
loc = -1
for i in range(n-1,-1,-1):
if tmp[i]!=l[i]:
loc = i
break
if loc==-1:
return ori
for i in range(n):
if tmp[loc]==l[i]:
l[loc],l[i] = l[i],l[loc]
break
ans = 0
for v in l[::-1]:
ans = ans*10+v
return ans
找到最初满足条件两个数
继续判断重复的有多少
def alternatingSubarray(nums):
"""
:type nums: List[int]
:rtype: int
"""
l = 0
n = len(nums)
ans =-1
while l<n-1:
if nums[l+1]!=nums[l]+1:
l+=1
continue
s = l
l+=2
while l<n and nums[l]==nums[l-2]:
l+=1
ans = max(ans,l-s)
l-=1
return ans
遍历每个坐标为峰值的情况
非递减单调栈
先从左往右依次入栈
pre[i]记录i位置为峰顶
左侧能够达到的最大值
同理从右往左相同处理suf[i]记录右侧能够达到最大值
相加减去重复的当前位置即为i位置为峰顶的结果
def maximumSumOfHeights(maxHeights):
"""
:type maxHeights: List[int]
:rtype: int
"""
n= len(maxHeights)
ans = 0
pre,suf=[0]*n,[0]*n
st1,st2=[],[]
for i in range(n):
while st1 and maxHeights[i]<maxHeights[st1[-1]]:
st1.pop()
if st1:
pre[i]=pre[st1[-1]]+(i-st1[-1])*maxHeights[i]
else:
pre[i]=(i+1)*maxHeights[i]
st1.append(i)
for i in range(n-1,-1,-1):
while st2 and maxHeights[i]<maxHeights[st2[-1]]:
st2.pop()
if st2:
suf[i]=suf[st2[-1]]+(st2[-1]-i)*maxHeights[i]
else:
suf[i]=(n-i)*maxHeights[i]
st2.append(i)
ans = max(ans,pre[i]+suf[i]-maxHeights[i])
return ans
func判断位置i是否有k个置位
通过num与num-1相与去除最低位的一个置位
mem存储已经判断过的数值 1位满足 0位不满足
def sumIndicesWithKSetBits(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
def func(num):
tag = 0
while tag<k and num>0:
num = num&(num-1)
tag+=1
if tag==k and num==0:
return True
return False
ans = 0
for i,num in enumerate(nums):
if func(i):
ans+=num
return ans
cnt[i][j]记录节点i到节点0的路径上权重为j的边数
对于两个节点a,b
lca为a,b最近公共祖先
那么在a,b路径上,权重为j的边数为cnt[a][j]+cnt[b][j]-2*cnt[lca][j]
权重最大为26 遍历每一种情况
def minOperationsQueries(n, edges, queries):
"""
:type n: int
:type edges: List[List[int]]
:type queries: List[List[int]]
:rtype: List[int]
"""
m,w=len(queries),26
nei = [{} for i in range(n)]
for ed in edges:
nei[ed[0]][ed[1]]=ed[2]
nei[ed[1]][ed[0]]=ed[2]
q = [[] for i in range(n)]
for i in range(m):
q[queries[i][0]].append([queries[i][1],i])
q[queries[i][1]].append([queries[i][0],i])
cnt=[[0 for _ in range(w+1)] for _ in range(n)]
visited = [0 for _ in range(n)]
uf = [0 for _ in range(n)]
lca = [0 for _ in range(m)]
def find(uf,i):
if uf[i]==i:
return i
uf[i] = find(uf,uf[i])
return uf[i]
def tarjan(node,parent):
if parent!=-1:
cnt[node] = cnt[parent][:]
cnt[node][nei[node][parent]]+=1
uf[node] = node
for c in nei[node].keys():
if c==parent:
continue
tarjan(c,node)
uf[c]=node
for [nd,ind] in q[node]:
if node!=nd and not visited[nd]:
continue
lca[ind] = find(uf,nd)
visited[node]=1
tarjan(0,-1)
ans = [0 for i in range(m)]
for i in range(m):
totalcnt,maxcnt = 0,0
for j in range(1,w+1):
t = cnt[queries[i][0]][j]+cnt[queries[i][1]][j]-2*cnt[lca[i]][j]
maxcnt = max(maxcnt,t)
totalcnt +=t
ans[i] = totalcnt-maxcnt
return ans
遍历每一台机子的情况
二分找到能够产生最大合金数
def maxNumberOfAlloys(n, k, budget, composition, stock, cost):
"""
:type n: int
:type k: int
:type budget: int
:type composition: List[List[int]]
:type stock: List[int]
:type cost: List[int]
:rtype: int
"""
ans = 0
for c in composition:
l,r = 0,budget+stock[0]
while l<r:
mid = (l+r+1)>>1
s = 0
for x,y,z in zip(c,stock,cost):
s += max(0,mid*x-y)*z
if s<=budget:
l = mid
else:
r = mid-1
ans = max(ans,l)
return ans
裴蜀定理
https://baike.baidu.com/item/%E8%A3%B4%E8%9C%80%E5%AE%9A%E7%90%86/5186593?fromtitle=%E8%B4%9D%E7%A5%96%E5%AE%9A%E7%90%86&fromid=5185441
每次操作
只会让桶的水总量增加x,y 或者减少x,y
找到x,y最大公约数并判断z是否是它的倍数
def canMeasureWater(jug1Capacity, jug2Capacity, targetCapacity):
"""
:type jug1Capacity: int
:type jug2Capacity: int
:type targetCapacity: int
:rtype: bool
"""
import math
if jug1Capacity+jug2Capacity<targetCapacity:
return False
if jug1Capacity==0 or jug2Capacity==0:
return targetCapacity==0 or jug1Capacity+jug2Capacity==targetCapacity
return targetCapacity%math.gcd(jug1Capacity,jug2Capacity)==0