记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
2/13 1234. 替换子串得到平衡字符串
对于剩余子串 只要所有字符出现次数少于等于s/4即可
待替换字符串使用滑动窗口l,r 从小到大枚举所有l
为了使[l,r]最小 需要找到最近的r
def balancedString(s):
"""
:type s: str
:rtype: int
"""
from collections import Counter
cnt = Counter(s)
ave = len(s)//4
def check():
if cnt['Q']>ave or cnt['W']>ave or cnt['E']>ave or cnt['R']>ave:
return False
return True
if check():
return 0
ans = len(s)
r = 0
for l,c in enumerate(s):
while r<len(s) and not check():
cnt[s[r]]-=1
r+=1
if not check():
break
ans = min(ans,r-l)
cnt[c]+=1
return ans
2/14 1124. 表现良好的最长时间段
大于8为1 小于等于8为-1
要求将某一段时间和大于0
前缀和 并用哈希表记录某一值第一次出现的位置
def longestWPI(hours):
"""
:type hours: List[int]
:rtype: int
"""
cur = 0
ans = 0
m = {}
for i,h in enumerate(hours):
if h>8:
cur+=1
else:
cur-=1
if cur>0:
ans = max(ans,i+1)
else:
if cur-1 in m:
ans = max(ans,i-m[cur-1])
if cur not in m:
m[cur]=i
return ans
2/15 1250. 检查「好数组」
只要两个数i,j最大公约数为1 可以得到ix-jy=1
只要数组内最大公约数为1既满足
def isGoodArray(nums):
"""
:type nums: List[int]
:rtype: bool
"""
from functools import reduce
from math import gcd
return reduce(gcd,nums)==1
2/16 2341. 数组能形成多少数对
遍历统计每个数出现次数
def numberOfPairs(nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
m={}
for num in nums:
m[num] = m.get(num,0)+1
a,b = 0,0
for v in m.values():
a += v//2
b += v%2
return [a,b]
2/17 1139. 最大的以 1 为边界的正方形
row,col分别记录行、列的前缀和
前缀和相减即可得到某行某列一段长度是否都为1
ans记录当前能够满足的最大边长
遍历每一个点从ans长度开始判断是否满足
判断四条边总和是否等于当前判断的长度cur
无论是否可以 不断增大直到无法满足
def largest1BorderedSquare(grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
ans = 0
m,n = len(grid),len(grid[0])
row,col = [[0]*(n+1) for _ in range(m)],[[0]*n for _ in range(m+1)]
for i in range(m):
for j in range(n):
row[i][j+1] = row[i][j]+grid[i][j]
for j in range(n):
for i in range(m):
col[i+1][j] = col[i][j]+grid[i][j]
for i in range(m):
for j in range(n):
if grid[i][j]==1:
cur = ans
while i+cur<m and j+cur<n:
if row[i][j+cur+1]-row[i][j]!=cur+1:
cur+=1
continue
if col[i+cur+1][j]-col[i][j]!=cur+1:
cur+=1
continue
if row[i+cur][j+cur+1]-row[i+cur][j]!=cur+1:
cur+=1
continue
if col[i+cur+1][j+cur]-col[i][j+cur]!=cur+1:
cur+=1
continue
cur+=1
ans = cur
return ans*ans
2/18 1237. 找出给定方程的正整数解
已知函数根据x,y都是单调递增的
如果f(x1,y1)=f(x2,y2)=z
x1<x2 则一定有y1>y2
可以从小到大遍历x 从大到小遍历y
def findSolution(customfunction, z):
"""
:type num: int
:type z: int
:rtype: List[List[int]]
"""
ans = []
y = 1000
for x in range(1,1001):
while y>0 and customfunction.f(x,y)>z:
y-=1
if y==0:
break
if customfunction.f(x,y)==z:
ans.append([x,y])
return ans
2/19 1792. 最大平均通过率
班级总数不变 最大平均通过率即为最大总通过率
当一个班级多一个通过的考生 通过率增加了 p = (pass+1)/(total+1)-pass/total
因为直接增加第二个学生所提高的通过率小于增加一个学生提高的通过率
我们可以一个一个增加学生 将所有班级的P从大到小排列
每一次取p最大的班级
def maxAverageRatio(classes, extraStudents):
"""
:type classes: List[List[int]]
:type extraStudents: int
:rtype: float
"""
def cal(p,t):
return 1.0*(p+1)/(t+1)-1.0*p/t
import heapq
h = []
total = 0
for p,t in classes:
total += 1.0*p/t
h.append((-cal(p,t),p,t))
heapq.heapify(h)
for _ in range(extraStudents):
v,p,t = heapq.heappop(h)
total -= v
heapq.heappush(h, (-cal(p+1,t+1),p+1,t+1))
return total/len(classes)