记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
7/21 1957. 删除字符使字符串变好
依次判断当前字符是否可以加入到答案中
def makeFancyString(s):
"""
:type s: str
:rtype: str
"""
ans=[]
for c in s:
if len(ans)>=2 and ans[-1]==ans[-2]==c:
continue
ans.append(c)
return ''.join(ans)
7/22 1695. 删除子数组的最大得分
即找到和最大的不含重复数字的子数组
def maximumUniqueSubarray(nums):
"""
:type nums: List[int]
:rtype: int
"""
ans=0
cur=0
s=set()
l,r=0,0
while r<len(nums):
while nums[r] in s:
num=nums[l]
cur-=num
s.remove(num)
l+=1
num=nums[r]
cur+=num
ans=max(ans,cur)
s.add(num)
r+=1
return ans
7/23 1717. 删除子字符串的最大得分
假设ab分数比ba高 如果不是则调换
将字符串内除了ab之外的字符看作分割点
对于只包含ab的字符串每次操作删除一个a,一个b 操作次数固定
所以先删除分数大的ab 可以得到更高的分数
numa,numb记录当前子字符串内a,b的个数
遍历当前字符c
如果c=a 先删除ab所以暂时不删除a numa+1
如果c=b 并且numa>0 可以删除ab并+x 否则numb+1
如果c是其他字符 则当前为分割点
对于子字符串内还有numa个a numb个b 删除ba 有min(numa,numb)个
def maximumGain(s, x, y):
"""
:type s: str
:type x: int
:type y: int
:rtype: int
"""
a,b="a","b"
if x<y:
a,b=b,a
x,y=y,x
ans=0
numa,numb=0,0
for c in s:
if c==a:
numa+=1
elif c==b:
if numa>0:
ans+=x
numa-=1
else:
numb+=1
else:
ans+=min(numa,numb)*y
numa,numb=0,0
ans+=min(numa,numb)*y
return ans
7/24 2322. 从树中删除边的最小分数
将0看作是根节点
删除两条边x1-y1,x2-y2三种情况
1.删除两条边在同一子树内 y1为x2的祖先
2.删除两条边在同一子树内 y2为x1的祖先
3.删除两条边属于不想交两个子树
https://leetcode.cn/problems/minimum-score-after-removals-on-a-tree/solutions/1625899/dfs-shi-jian-chuo-chu-li-shu-shang-wen-t-x1kk/?envType=daily-question&envId=2025-07-24
def minimumScore(nums, edges):
"""
:type nums: List[int]
:type edges: List[List[int]]
:rtype: int
"""
n=len(nums)
g=[[]for _ in range(n)]
for x,y in edges:
g[x].append(y)
g[y].append(x)
xor,in_,out=[0]*n,[0]*n,[0]*n
global clc
clc=0
def dfs(x,fa):
global clc
clc+=1
in_[x]=clc
xor[x]=nums[x]
for y in g[x]:
if y!=fa:
dfs(y,x)
xor[x]^=xor[y]
out[x]=clc
dfs(0,-1)
def isfa(x,y):
return in_[x]<in_[y]<=out[x]
ans=float("inf")
for x in range(2,n):
for y in range(1,x):
if isfa(x, y):
a,b,c=xor[y],xor[x]^xor[y],xor[0]^xor[x]
elif isfa(y, x):
a,b,c=xor[x],xor[x]^xor[y],xor[0]^xor[y]
else:
a,b,c=xor[x],xor[y],xor[0]^xor[x]^xor[y]
ans=min(ans,max(a,b,c)-min(a,b,c))
if ans==0:
return ans
return ans
7/25 3487. 删除后的最大子数组元素和
可以看做删除到最后 只剩下一个满足条件的子数组
不存在重复数值和负数
去重 排序
从大往小加直至遇到负数
因为至少要存在一个数 不论正负
所以先将最大的那个加入答案
def maxSum(nums):
"""
:type nums: List[int]
:rtype: int
"""
s=sorted(list(set(nums)))
ans=s[-1]
for num in s[-2::-1]:
if num<0:
break
ans+=num
return ans
7/26 3480. 删除一个冲突对后最大子数组数目
确定左端点i, 如果一个冲突对a,b
如果a<i 那么右端点j取任何值都不会包含a,b
如果a>=i 那么右端点j<min(b,n+1)
使用bm1,bm2记录同一个a 最小b和次小b
使用delcnt[ib1]记录删除b1后 增加的个数min(min(b2,bm2[ib1]),n+1)-min(b1,n+1)
def maxSubarrays(n, conflictingPairs):
"""
:type n: int
:type conflictingPairs: List[List[int]]
:rtype: int
"""
bm1,bm2=[2**31-1]*(n+1),[2**31-1]*(n+1)
for p in conflictingPairs:
a,b=min(p[0],p[1]),max(p[0],p[1])
if bm1[a]>b:
bm2[a]=bm1[a]
bm1[a]=b
elif bm2[a]>b:
bm2[a]=b
ans=0
ib1=n
b2=2**31-1
delcnt=[0]*(n+1)
for i in range(n,0,-1):
if bm1[ib1]>bm1[i]:
b2=min(b2,bm1[ib1])
ib1=i
else:
b2=min(b2,bm1[i])
ans+=min(bm1[ib1],n+1)-i
delcnt[ib1]+=min(min(b2,bm2[ib1]),n+1)-min(bm1[ib1],n+1)
return ans+max(delcnt)
7/27 2210. 统计数组中峰和谷的数量
去除相连重复数值 再判断峰谷
def countHillValley(nums):
"""
:type nums: List[int]
:rtype: int
"""
k=1
for i in range(1,len(nums)):
if nums[i]!=nums[i-1]:
nums[k]=nums[i]
k+=1
ans=0
for i in range(1,k-1):
if (nums[i-1]<nums[i]) == (nums[i]>nums[i+1]):
ans+=1
return ans