LeetCode 每日一题 2026/8/10-2026/8/16
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 8/10 1510. 石子游戏 IV
- 8/11 2996. 大于等于顺序前缀和的最小缺失整数
- 8/12 2958. 最多 K 个重复元素的最长子数组
- 8/13 2213. 由单个字符重复的最长子字符串
- 8/14 3090. 每个字符最多出现两次的最长子字符串
- 8/15
- 8/16
8/10 1510. 石子游戏 IV
双方轮流从 n 个石子中拿走平方数个,Alice 先手,不能行动者输。
用 dp[i] 表示还剩 i 个石子时,当前选手是否必胜。
转移:若存在某个平方数 x,使得 dp[i-x] 为败,则当前选手必胜。
最终返回 dp[n]。
defwinnerSquareGame(n):""" :type n: int :rtype: bool """dp=[False]*(n+1)foriinrange(1,n+1):k=1whilek*k<=i:ifnotdp[i-k*k]:dp[i]=Truebreakk+=1returndp[n]8/11 2996. 大于等于顺序前缀和的最小缺失整数
从头遍历 找到顺序前缀并记录和
顺序前缀结束后
判断和是否出现过 若出现+1
defmissingInteger(nums):""" :type nums: List[int] :rtype: int """ans=nums[0]foriinrange(1,len(nums)):ifnums[i]-nums[i-1]==1:ans+=nums[i]else:breaks=set(nums)whileansins:ans+=1returnans8/12 2958. 最多 K 个重复元素的最长子数组
滑动窗口[l,r] cnt[num]记录 num出现的次数
r一直往右移动 将nums[r]加入cnt 如果cnt[nums[r]] > k 则将nums[l]从cnt中移除 并左移l
如果cnt[nums[r]] <= k 则更新max_length
defmaxSubarrayLength(nums,k):""" :type nums: List[int] :type k: int :rtype: int """fromcollectionsimportdefaultdict left=0right=0max_length=0cnt=defaultdict(int)whileright<len(nums):cnt[nums[right]]+=1whilecnt[nums[right]]>k:cnt[nums[left]]-=1left+=1max_length=max(max_length,right-left+1)right+=1returnmax_length8/13 2213. 由单个字符重复的最长子字符串
每次单点改字符后,要求整串中最长连续相同字符的长度。
用线段树维护每个区间的:左端连续长度 lmx、右端连续长度 rmx、区间内最长连续长度 mx。
合并左右子区间时,若左区间右端字符等于右区间左端字符,则可把左后缀和右前缀拼起来更新 mx;若左区间整段相同,lmx 还要加上右前缀;若右区间整段相同,rmx 还要加上左后缀。
每次修改叶子后自底向上 pushup,根节点的 mx 就是当前答案。
deflongestRepeating(s,queryCharacters,queryIndices):""" :type s: str :type queryCharacters: str :type queryIndices: List[int] :rtype: List[int] """n=len(s)chars=list(s)lmx=[0]*(n*4)rmx=[0]*(n*4)mx=[0]*(n*4)left=[0]*(n*4)right=[0]*(n*4)defpushup(u):ls,rs=u<<1,u<<1|1a=right[ls]-left[ls]+1b=right[rs]-left[rs]+1lmx[u]=lmx[ls]rmx[u]=rmx[rs]mx[u]=mx[ls]ifmx[ls]>mx[rs]elsemx[rs]ifchars[right[ls]-1]==chars[left[rs]-1]:iflmx[ls]==a:lmx[u]+=lmx[rs]ifrmx[rs]==b:rmx[u]+=rmx[ls]cross=rmx[ls]+lmx[rs]ifcross>mx[u]:mx[u]=crossdefbuild(u,l,r):left[u]=l right[u]=rifl==r:lmx[u]=rmx[u]=mx[u]=1returnmid=(l+r)>>1build(u<<1,l,mid)build(u<<1|1,mid+1,r)pushup(u)defmodify(u,x,v):ifleft[u]==right[u]:chars[x-1]=vreturnmid=(left[u]+right[u])>>1ifx<=mid:modify(u<<1,x,v)else:modify(u<<1|1,x,v)pushup(u)build(1,1,n)ans=[]forx,vinzip(queryIndices,queryCharacters):modify(1,x+1,v)ans.append(mx[1])returnans8/14 3090. 每个字符最多出现两次的最长子字符串
滑动窗口 cnt记录每个字符出现的次数
如果当前字符出现的次数大于2,则移动左指针,直到当前字符出现的次数小于等于2
defmaximumLengthSubstring(s):""" :type s: str :rtype: int """l,r=0,0res=0cnt=defaultdict(int)whiler<len(s):cnt[s[r]]+=1whilecnt[s[r]]>2:cnt[s[l]]-=1l+=1res=max(res,r-l+1)r+=1returnres