记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
8/9 313. Super Ugly Number 超级丑数
除1外 大的丑数必定是小的丑数乘以primes中的一个质数
l记录当前丑数
p[i]记录质数i在序列中乘的一个小丑数位置
比较所有ip[i] 找到最小的tmp及为下一个丑数
将所有满足tmp==ip[i]的质数i的位置后移一位 p[i]++
def nthSuperUglyNumber(n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
"""
p = {}
for i in primes:
p[i]=0
l = [1]
loc = 0
while loc<n-1:
loc +=1
tmp = min([i*l[p[i]] for i in primes])
l.append(tmp)
for i in primes:
if i*l[p[i]]==tmp:
p[i]+=1
return l[n-1]
8/10 413. Arithmetic Slices 等差数列划分
计算差分数组
获取连续相等的差长度 计算这个长度能够组成的
def numberOfArithmeticSlices(nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums)<3:
return 0
diff = []
for i in range(1,len(nums)):
diff.append(nums[i]-nums[i-1])
l,r = 0,0
ans = 0
while r<len(diff):
if diff[l]!=diff[r]:
ans +=(r-l-1)*(r-l)//2
l = r
r+=1
ans +=(r-l-1)*(r-l)//2
return ans
8/11 446. Arithmetic Slices II - Subsequence 等差数列划分 II - 子序列
dp
dp[i][d] 定义为以nums[i]为末尾 d位公差 至少存在两个元素的数列个数
遍历每个元素对 nums[j],nums[i] j<i d=nums[i]-nums[j]
此时 dp[j][d]的所有数列加上nums[i] 必定组成了三个元素及以上的等差数列 ans+=nums[j][d]
dp[i][d] += dp[j][d]+1
def numberOfArithmeticSlices(nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
if n<3:
return 0
from collections import defaultdict
dp = [defaultdict(int) for _ in range(n)]
ans = 0
for i in range(n):
for j in range(i):
d = nums[i]-nums[j]
ans += dp[j][d]
dp[i][d] += dp[j][d]+1
return ans
8/12 516. Longest Palindromic Subsequence 最长回文子序列
dp
dp[i][j] 表示[i,j]之间的最长回文子序列
初始化dp[i][i]==1
如果s[i]==s[j] 则dp[i][j]=dp[i+1][j-1]+2
否则 找到max(dp[i+1][j],dp[i][j-1])
def longestPalindromeSubseq(s):
"""
:type s: str
:rtype: int
"""
n = len(s)
dp = [[0]*n for _ in range(n)]
for i in range(n):
dp[i][i]=1
for i in range(n-1,-1,-1):
for j in range(i+1,n):
if s[i]==s[j]:
dp[i][j]=dp[i+1][j-1]+2
else:
dp[i][j] = max(dp[i+1][j],dp[i][j-1])
return dp[0][n-1]
8/13 233. Number of Digit One 数字 1 的个数
考虑每一位1出现的次数
i代表当前位数因子 10**位数(从0开始)
对于当前为cur=num%10 其左边高位为num//10 右边低位为n%i
分情况考虑
如果cur0:
在当前为出现1的次数只与高位相关 [0,num//10) 个数为num//10 * i
如果cur1:
与高位低位都有关 及cur=0时的结果加上cur=1时低位的个数 num//10i+(n%i+1)
如果cur>1:
只与高位有关 cur=0时num//10i个以及cur=1时i个 num//10*i+i
def countDigitOne(n):
"""
:type n: int
:rtype: int
"""
i = 1
s = 0
num = n
while num>0:
if num%10==0:
s+=(num//10)*i
if num%10==1:
s+=(num//10)*i+(n%i)+1 ##119 11%10==1 10~19需要补充
if num%10>1:
s+=(num//10)*i+i
num=num//10
i*=10
return s
8/14 1583. Count Unhappy Friends 统计不开心的朋友
order[x][y] 用来记录x与y的亲近程度 index 越靠前越亲近
couple[x]=y 记录当前x配对的y
得到当前配对的x,y 的亲近程度index
遍历[0,index) 的u
如果当前u的亲近程度order[u][v]>order[u][x] 则x不开心
def unhappyFriends(n, preferences, pairs):
"""
:type n: int
:type preferences: List[List[int]]
:type pairs: List[List[int]]
:rtype: int
"""
order = [[0]*n for _ in range(n)]
for i in range(n):
for j in range(n-1):
order[i][preferences[i][j]] = j
couple = [0]*n
for x,y in pairs:
couple[x]=y
couple[y]=x
ans = 0
for x in range(n):
y = couple[x]
index = order[x][y]
for i in range(index):
u = preferences[x][i]
v = couple[u]
if order[u][x]<order[u][v]:
ans +=1
break
return ans
8/15 576. Out of Boundary Paths 出界的路径数
move 为移动的四个方向
mem 记录在x,y上移动steps步数 出界的可能性 放置重复计算
对于位置x,y遍历四个方向
如果界内 则继续考虑界内的情况
如果出界 那么ans+1
def findPaths(m, n, maxMove, startRow, startColumn):
"""
:type m: int
:type n: int
:type maxMove: int
:type startRow: int
:type startColumn: int
:rtype: int
"""
MOD = 10**9+7
move = [(1,0),(0,1),(-1,0),(0,-1)]
mem = {}
def find(x,y,steps):
if (x,y,steps) in mem:
return mem[(x,y,steps)]
if steps==0:
return 0
ans = 0
for i,j in move:
xx,yy = x+i,y+j
if 0<=xx<m and 0<=yy<n:
ans += find(xx,yy,steps-1)
else:
ans +=1
ans = ans%MOD
mem[(x,y,steps)] = ans
return ans
return find(startRow, startColumn,maxMove)