[Leetcode Weekly Contest]181
链接:LeetCode
[Leetcode]1389. 按既定顺序创建目标数组
给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:
- 目标数组 target 最初为空。
- 按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
- 重复上一步,直到在 nums 和 index 中都没有要读取的元素。
请你返回目标数组。
题目保证数字插入位置总是存在。
直接insert即可,如下。
class Solution:
def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
res = []
for i in range(len(index)):
res.insert(index[i],nums[i])
return res
[Leetcode]1390. 四因数
给你一个整数数组 nums,请你返回该数组中恰有四个因数的这些整数的各因数之和。
如果数组中不存在满足题意的整数,则返回 0 。
示例:
输入:\(nums = [21,4,7]\)
输出:32
解释:
21 有 4 个因数:1, 3, 7, 21
4 有 3 个因数:1, 2, 4
7 有 2 个因数:1, 7
答案仅为 21 的所有因数的和。
除了暴力方法去求整数因数的个数,一个比较巧妙的想法是:四个因数就是能够分解成两个质数乘积的数或者是立方数。
比如:
21 = 3 * 7
8 = 2 * 4
class Solution:
def sumFourDivisors(self, nums: List[int]) -> int:
if not nums:
return 0
max_num = max(nums)
isPrim = [True for _ in range(max_num)]
for i in range(2,max_num):
if not isPrim[i]:continue
isPrim[i+i:max_num:i] = [False] * len(isPrim[i+i:max_num:i])
# 把素数都提取出来
prims = [i for i in range(2, max_num) if isPrim[i]]
res = 0
for num in nums:
for prim in prims:
if prim * prim > num:
break
elif prim * prim * prim == num:
res += (1 + num + prim + prim * prim)
elif num % prim == 0 and isPrim[num // prim] and prim * prim != num:
res += (1 + num + prim + num // prim)
return res
[Leetcode]1391. 检查网格中是否存在有效路径
给你一个 m x n 的网格 grid。网格里的每个单元都代表一条街道。\(grid[i][j]\)的街道可以是:
- 1 表示连接左单元格和右单元格的街道。
- 2 表示连接上单元格和下单元格的街道。
- 3 表示连接左单元格和下单元格的街道。
- 4 表示连接右单元格和下单元格的街道。
- 5 表示连接左单元格和上单元格的街道。
- 6 表示连接右单元格和上单元格的街道。
你最开始从左上角的单元格 (0,0) 开始出发,网格中的「有效路径」是指从左上方的单元格 (0,0) 开始、一直到右下方的 (m-1,n-1) 结束的路径。该路径必须只沿着街道走。
如果网格中存在有效的路径,则返回 true,否则返回 false 。
一道图遍历的题目,难点在于单元的表示和判断是否存在环。这里通过BFS,新建一个队列,每次判断是否能进入下一个单元,以及进入的路径。如下。
import collections
class Solution:
def hasValidPath(self, grid: List[List[int]]) -> bool:
dir = {1:[(0,1),(0,-1)],
2:[(1,0),(-1,0)],
3:[(1,0),(0,-1)],
4:[(0,1),(1,0)],
5:[(0,-1),(-1,0)],
6:[(0,1),(-1,0)]}
queue = collections.deque()
queue.append([0,0])
m,n = len(grid),len(grid[0])
if n==m==1:
return True
while queue:
x,y = queue.popleft()
for dx,dy in dir[grid[x][y]]:
nx,ny = x+dx,y+dy
if 0<=nx<m and 0<=ny<n and grid[nx][ny]!=-1:
for ndx,ndy in dir[grid[nx][ny]]:
if ndx+dx==0 and ndy+dy==0:
if nx==m-1 and ny==n-1:
return True
queue.append((nx,ny))
grid[x][y]=-1
return False
[Leetcode]1392. 最长快乐前缀
「快乐前缀」是在原字符串中既是 非空 前缀也是后缀(不包括原字符串自身)的字符串。
给你一个字符串 s,请你返回它的 最长快乐前缀。
如果不存在满足题意的前缀,则返回一个空字符串。
KMP 算法中的 next 数组描述的就是字符串中前缀与后缀的最长匹配长度,注意这里要加一个特殊字符,这样next最后一个值才表示整个字符串的最长前后缀。
class Solution:
def longestPrefix(self, s: str) -> str:
next = self.get_next(s+'*')
return s[:next[-1]]
def get_next(self,p):
len_p = len(p)
next = [-1 for i in range(len_p)]
j,k = 0,-1
while j<len_p-1:
if p[j] == p[k] or k==-1:
j+=1
k+=1
next[j] = k
else:
k = next[k]
return next
参考:
四因数