1.用栈操作构建数组
思路:
遍历list数组,判断当前值是否在目标数组target中?若在,则仅入栈;反之,入栈➕出栈。(分别对应在返回数组中添加“Push”或添加“Push”+“Pop”)。
class Solution(object):
def buildArray(self, target, n):
"""
:type target: List[int]
:type n: int
:rtype: List[str]
"""
res, k, l = [], 0, len(target)
for i in range(1,n+1):
res.append("Push")
if i not in target:
res.append("Pop")
else:
k += 1
if k == l:
return res
2.形成两个异或相等数组的三元组数目
思路:基本的动态规划
dp[i][j] 表示从索引i到索引j的按位异或值。
遍历i,j,k的所有可能,当dp[i][j-1] == dp[j][k] 时,计数器加1。
要注意的是,i可以等于0,j必须大于i,j可以等于k这个条件。
class Solution(object):
def countTriplets(self, arr):
"""
:type arr: List[int]
:rtype: int
"""
#i,j,k
l = len(arr)
dp = [[0 for i in range(l)] for j in range(l)]
for i in range(l):
for j in range(l):
if i == j:
dp[i][j] = arr[i]
elif i < j:
dp[i][j] = arr[j] ^ dp[i][j-1]
cnt = 0
#遍历i,j,k
for i in range(l):
for j in range(i+1,l):
for k in range(j,l):
if dp[i][j-1] == dp[j][k]:
cnt += 1
return cnt
3.收集树上所有苹果的最少时间
思路:
- 遍历树集合;
- 当树上有苹果时,遍历其根节点直到根节点的编号为0;
- 当该路径是第一次走时,花费时间增加2秒钟。
- 所有树遍历结束,返回花费的时间。
如何知道当前路径是第一次走的?
- 存储每个树的根节点。则一条完整的路径是由k个子树到其根树的短路径组成。比如0-4是由4-1和1-0组成的。
- 每次只需判断苹果树到根节点的路径上的短路径是否经过过。
class Solution(object):
def minTime(self, n, edges, hasApple):
"""
:type n: int
:type edges: List[List[int]]
:type hasApple: List[bool]
:rtype: int
"""
dic = {}
l = len(edges)
for i in range(l):
dic[edges[i][1]] = edges[i][0]
#编号为0的节点的根节点为空
dic[0] = None
cnt = 0
ways = set()
for i in range(n):
if hasApple[i]:
t = i
#遍历当前节点的根节点直至到0节点
while dic[t] != None:
#判断是否已经经过。
if (t,dic[t]) not in ways:
cnt += 2
ways.add((t,dic[t]))
t = dic[t]
else:
break
return cnt
4.切披萨的方案数
思路:动态规划
比赛时卡了好久,当时是用的递归,遍历了所有可能情况,但这显然太慢了,解决不了问题。
- 辅助cou_A,cou_A[i][j]代表披萨左上角的坐标为[i,j]时,当前披萨上的苹果数量。因为每次切完,得到的披萨是由一个点的及其右面和下面所有的点组成。这个点就是当前披萨最左上角的坐标。
- 转移方程:cou_A[i][j] = cou_A[i+1][j+1] + cou_A[i+1][j] - cou_A[i+1][j+1] + cou_A[i][j+1] - cou_A[i+1][j+1] 及当前苹果数量等于其右下边苹果数量加上当前行右边的苹果数量,再加上当前列下边的苹果数量。若当前坐标下是苹果,则cou_A[i][j] += 1
- 三维dp数组,dp[i][j][k]代表,经过k次切割得到左上角坐标为[i,j]的披萨的方案数。
- dp[i][j][k]由两种方式得到,已经切k-1刀时,由其上边所有行横切一刀得到,或从其左边所有列竖切一刀得到。
- dp[i][j][k]的初始值:dp[0][0][0] = 1,一刀都没切,得到一整块披萨的方案数为1。
- 最后遍历dp[i][j][k],k=k-1时的方案数。
class Solution(object):
def ways(self, pizza, k):
"""
:type pizza: List[str]
:type k: int
:rtype: int
"""
rows, cols = len(pizza), len(pizza[0])
cou_A = [[0 for i in range(cols+1)] for j in range(rows+1)]
i = rows-1
while i >= 0:
j = cols-1
while j >= 0:
cou_A[i][j] = cou_A[i+1][j+1] + cou_A[i][j+1] - cou_A[i+1][j+1] + cou_A[i+1][j] - cou_A[i+1][j+1]
if pizza[i][j] == 'A':
cou_A[i][j] += 1
j -= 1
i -= 1
#切k-1次
dp = [[[0 for i in range(k)] for j in range(cols)] for t in range(rows)]
dp[0][0][0] = 1
cnt = 0
for t in range(1,k):
for i in range(rows):
for j in range(cols):
x, y = 0, 0
if cou_A[i][j] > 0:
while x < i:
if cou_A[x][j] - cou_A[i][j] > 0:
dp[i][j][t] += dp[x][j][t-1]
x += 1
while y < j:
if cou_A[i][y] - cou_A[i][j] > 0:
dp[i][j][t] += dp[i][y][t-1]
y += 1
#print dp[i][j][t]
for i in range(rows):
for j in range(cols):
cnt += dp[i][j][k-1]
return cnt % (10**9+7)
5.周赛成绩
leetcode全国排名第一次进前1000哇…之前4道题全ak都没进过。