记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
-
-
- [5/12 2094. 找出 3 位偶数](#5/12 2094. 找出 3 位偶数)
- [5/13 3335. 字符串转换后的长度 I](#5/13 3335. 字符串转换后的长度 I)
- [5/14 3337. 字符串转换后的长度 II](#5/14 3337. 字符串转换后的长度 II)
- [5/15 2900. 最长相邻不相等子序列 I](#5/15 2900. 最长相邻不相等子序列 I)
- [5/16 2901. 最长相邻不相等子序列 II](#5/16 2901. 最长相邻不相等子序列 II)
- [5/17 75. 颜色分类](#5/17 75. 颜色分类)
- [5/18 1931. 用三种不同颜色为网格涂色](#5/18 1931. 用三种不同颜色为网格涂色)
-
5/12 2094. 找出 3 位偶数
统计每个数字个数
python
def findEvenNumbers(digits):
"""
:type digits: List[int]
:rtype: List[int]
"""
nums=[0]*10
for num in digits:
nums[num]+=1
ans=[]
for a in range(1,10):
if nums[a]>0:
nums[a]-=1
for b in range(10):
if nums[b]>0:
nums[b]-=1
for c in range(0,10,2):
if nums[c]>0:
ans.append(100*a+10*b+c)
nums[b]+=1
nums[a]+=1
return ans
5/13 3335. 字符串转换后的长度 I
统计各个字符出现个数0~25
每一次将个数往右移动 如果在最后则将0,1 +1
python
def lengthAfterTransformations(s, t):
"""
:type s: str
:type t: int
:rtype: int
"""
MOD=10**9+7
cnt=[0]*26
for c in s:
cnt[ord(c)-ord("a")]+=1
for _ in range(t):
nxt=[0]*26
nxt[0]=cnt[25]
nxt[1]=cnt[25]+cnt[0]
for i in range(2,26):
nxt[i]=cnt[i-1]
cnt=nxt
ans=sum(cnt)%MOD
return ans
5/14 3337. 字符串转换后的长度 II
矩阵快速幂
python
def lengthAfterTransformations(s, t, nums):
"""
:type s: str
:type t: int
:type nums: List[int]
:rtype: int
"""
from collections import Counter
MOD=10**9+7
def mul(a,b):
return [[sum(x*y for x,y in zip(row,col))%MOD for col in zip(*b)]
for row in a]
def pow_mul(a,n,f):
ans = f
while n:
if n&1:
ans=mul(a,ans)
a=mul(a,a)
n>>=1
return ans
m=[[0]*26 for _ in range(26)]
for i,c in enumerate(nums):
for j in range(i+1,i+c+1):
m[i][j%26]=1
f=[[1] for _ in range(26)]
mt=pow_mul(m, t, f)
ans=0
for c,cnt in Counter(s).items():
ans+=mt[ord(c)-ord('a')][0]*cnt
return ans%MOD
5/15 2900. 最长相邻不相等子序列 I
将groups看作是一个01字符串 相同的为一部分
即从各个部分中取一个即可
001011 取0101
python
def getLongestSubsequence(words, groups):
"""
:type words: List[str]
:type groups: List[int]
:rtype: List[str]
"""
n=len(groups)
ans=[]
for i,c in enumerate(groups):
if i==n-1 or c!=groups[i+1]:
ans.append(words[i])
return ans
5/16 2901. 最长相邻不相等子序列 II
dp[i]代表i结尾最长子序列长度
j从0~i-1 找到最大的dp[i]=max(dp[i],dp[j]+1)
ham(a,b)用来求a,b的汉明距离
pre[i]代表当前dp[i]的前一个位置 方便最后倒序得到结果
python
def getWordsInLongestSubsequence(words, groups):
"""
:type words: List[str]
:type groups: List[int]
:rtype: List[str]
"""
n=len(groups)
dp=[1]*n
pre=[-1]*n
maxind=0
def ham(a,b):
if len(a)!=len(b):
return False
diff=0
for i in range(len(a)):
if a[i]!=b[i]:
diff+=1
if diff>1:
return False
return diff==1
for i in range(1,n):
for j in range(i):
if ham(words[i],words[j]) and dp[j]+1>dp[i] and groups[i]!=groups[j]:
dp[i]=dp[j]+1
pre[i]=j
if dp[i]>dp[maxind]:
maxind=i
ans=[]
i=maxind
while i>=0:
ans = [words[i]]+ans
i=pre[i]
return ans
5/17 75. 颜色分类
设定三个坐标i,j,k
i用来记录可与0调换的位置 j用来记录可与2调换的位置 k用来扫描整个list
当k扫描到2时 将这个2与j上的调换 将2放到后面 j往前移 (此时不知道被调过来的数 需要重新扫描 所以k不需要往后移)
当k扫描到0时 将这个0与i上的调换 将0放到后面 i,k往后移 (此时调过来的数是在前面已经扫描过的 所以k往后移)
当k扫描到1时 不做处理 k往后移
python
def sortColors(nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
i = 0
k = 0
j = len(nums)-1
while k<=j:
if nums[k]==2:
nums[k],nums[j] = nums[j],nums[k]
j-=1
elif nums[k]==0:
nums[i],nums[k] = nums[k],nums[i]
k+=1
i+=1
else:
k+=1
5/18 1931. 用三种不同颜色为网格涂色
用m位三进制数表示三种颜色的可能
在valid中存储没有相邻同色的三进制数
nxt[i]记录第i种排列后可以接的其他排列
dfs(i,j) 第i行选择第j种排列的方案数量 记忆化搜索
python
def colorTheGrid(m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
pow3=[3**i for i in range(m)]
valid=[]
for color in range(3**m):
for i in range(1,m):
if color//pow3[i]%3==color//pow3[i-1]%3:
break
else:
valid.append(color)
nv=len(valid)
nxt=[[] for _ in range(nv)]
for i,c1 in enumerate(valid):
for j,c2 in enumerate(valid):
for p3 in pow3:
if c1//p3%3==c2//p3%3:
break
else:
nxt[i].append(j)
MOD=10**9+7
mem={}
def dfs(i,j):
if (i,j)in mem:
return mem[(i,j)]
if i==0:
return 1
ans=sum(dfs(i-1,k) for k in nxt[j])%MOD
mem[(i,j)]=ans
return ans
return sum(dfs(n-1,j) for j in range(nv))%MOD