前文
继上一篇,[Leetcode题medium11/15/16/18/31/33/34/39/40,Python多种解法(三)(https://blog.youkuaiyun.com/weixin_42681866/article/details/88597930),我们继续Array medium题目的解法分享。
48. Rotate Image
class Solution(object):
"""
利用zip的特性,可以针对集合里的元素进行第一个、第二个依次拼接,完美达到题目要求
Runtime: 20 ms, faster than 100.00% of Python online submissions for Rotate Image.
Memory Usage: 10.6 MB, less than 86.93% of Python online submissions for Rotate Image.
"""
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: None Do not return anything, modify matrix in-place instead.
"""
matrix[::] = zip(*matrix[::-1])
class Solution1(object):
"""
先上下翻转,再以左上方到右下方斜线不动,进行翻转
[
[1,2,3],
[4,5,6],
[7,8,9]
]
[
[7,8,9],
[4,5,6],
[1,2,3]
]
Runtime: 20 ms, faster than 100.00% of Python online submissions for Rotate Image.
Memory Usage: 11 MB, less than 5.30% of Python online submissions for Rotate Image.
"""
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
if matrix:
rows = len(matrix)
cols = len(matrix[0])
for i in range(rows // 2):
for j in range(cols):
matrix[i][j], matrix[rows - i - 1][j] = matrix[rows - i - 1][j], matrix[i][j]
for i in range(rows):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
class Solution2(object):
"""
先调换4个角,再依次调换边
Runtime: 24 ms, faster than 91.14% of Python online submissions for Rotate Image.
Memory Usage: 10.8 MB, less than 23.67% of Python online submissions for Rotate Image.
"""
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
n = len(matrix)
for l in range(n // 2):
r = n - 1 - l
for p in range(l, r):
q = n - 1 - p
cache = matrix[l][p]
matrix[l][p] = matrix[q][l]
matrix[q][l] = matrix[r][q]
matrix[r][q] = matrix[p][r]
matrix[p][r] = cache
54. Spiral Matrix
class Solution(object):
"""
讨论区大神一行解决,代码理解是and前后为真则返回后者,那当matrix为空的时候,执行pop会报错,此时返回matrix
matrix.pop(0)每次返回第一行数,而后段代码递归调用,以示例为例,第一次返回[(6, 9), (5, 8), (4, 7)],因为
被下一次pop出(6,9),第二次返回[(8,7),(5,4)],最后拼接即是答案
Runtime: 40 ms, faster than 31.27% of Python3 online submissions for Spiral Matrix.
Memory Usage: 13.2 MB, less than 5.18% of Python3 online submissions for Spiral Matrix.
"""
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
return matrix and [*matrix.pop(0)] + self.spiralOrder([*zip(*matrix)][::-1])
class Solution2(object):
"""
正常思路,代码看的是真的舒服,即依次定义row、col,按照逻辑,先返回第一行,然后依次取每行的最后一个数,
接着返回最后一行从后往前,最后返回每行的第一个数。然后循环此段操作。
当l==r,说明只剩中间一行,直接reverse即可;当u==d,说明只剩中间一列,直接颠倒即可。
Runtime: 36 ms, faster than 51.51% of Python3 online submissions for Spiral Matrix.
Memory Usage: 13.2 MB, less than 5.18% of Python3 online submissions for Spiral Matrix.
"""
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return []
ans = []
m, n = len(matrix), len(matrix[0])
u, d, l, r = 0, m - 1, 0, n - 1
while l < r and u < d:
ans.extend([matrix[u][j] for j in range(l, r)])
ans.extend([matrix[i][r] for i in range(u, d)])
ans.extend([matrix[d][j] for j in range(r, l, -1)])
ans.extend([matrix[i][l] for i in range(d, u, -1)])
u, d, l, r = u + 1, d - 1, l + 1, r - 1
if l == r:
ans.extend([matrix[i][r] for i in range(u, d + 1)])
elif u == d:
ans.extend([matrix[u][j] for j in range(l, r + 1)])
return ans
55. Jump Game
class Solution:
"""
贪心算法,每一步都算上一个数的索引和它的值的和是否有能力到达这一个数,如果可以的话,则说明有能力到达最后一个数,
不行的话就直接返回False
Runtime: 48 ms, faster than 73.92% of Python3 online submissions for Jump Game.
Memory Usage: 14.7 MB, less than 5.28% of Python3 online submissions for Jump Game.
"""
def canJump(self, nums: List[int]) -> bool:
reach = 0
for i in range(len(nums)):
if i > reach:
return False
reach = max(reach, i+nums[i])
return True
56. Merge Intervals
class Solution:
"""
题目的要求是针对itervals里的所有集合做区间判断,如果有重叠的区间就合并,那就有以下几种情况:
1.[1,3],[2,4]==>第二个的start小于第一个的end,第一个的end小于第二个的end
2.[1,4],[2,3]==>第二个的start小于第一个的end,第二个的end小于第一个的end
3.[2,4],[1,3]==>第二个的start大于第一个的start,通过排序解决该情况,则转换为第1、2种
4.[1,2],[3,4]==>即没有重叠空间
所以如果排完序后,就剩1,2两种情况,本质是比较第一个和第二个的end,转为代码如下
Runtime: 60 ms, faster than 80.12% of Python3 online submissions for Merge Intervals.
Memory Usage: 15.9 MB, less than 5.34% of Python3 online submissions for Merge Intervals.
"""
def merge(self, intervals: List[Interval]) -> List[Interval]:
out = []
for i in sorted(intervals, key=lambda i:i.start):
if out and i.start <= out[-1].end:
out[-1].end = max(i.end, out[-1].end)
else:
out.append(i)
return out
59. Spiral Matrix II
class Solution:
"""
解法沿用54,Sprial Matrix的解法,定义u\d\l\r四个变量,以3*3为例,分为上、右、下、左四层,然后每层循环遍历出各自的数,
最后再得出9所在的中心位置,如果超过3*3,则在while里循环一次
Runtime: 40 ms, faster than 51.34% of Python3 online submissions for Spiral Matrix II.
Memory Usage: 13.1 MB, less than 5.40% of Python3 online submissions for Spiral Matrix II.
"""
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0] * n for _ in range(n)]
x, u, d, l, r = 1, 0, n - 1, 0, n - 1
# x is the next value to write
# u and d are upper and lower bound of current square/rectangle
# l and r are left and right bound of current square/rectangle
while l < r and u < d:
for j in range(l, r):
matrix[u][j] = x
x += 1
for i in range(u, d):
matrix[i][r] = x
x += 1
for j in range(r, l, -1):
matrix[d][j] = x
x += 1
for i in range(d, u, -1):
matrix[i][l] = x
x += 1
u, d, l, r = u + 1, d - 1, l + 1, r - 1
if l == r:
matrix[u][r] = x
return matrix
class Solution1(object):
"""
讨论区解法1,在上述解法上直接优化了三次遍历,牛皮!
Runtime: 20 ms, faster than 100.00% of Python online submissions for Spiral Matrix II.
Memory Usage: 10.8 MB, less than 26.97% of Python online submissions for Spiral Matrix II.
"""
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
A = [[0] * n for _ in range(n)]
i, j, di, dj = 0, 0, 0, 1
for k in xrange(n*n):
A[i][j] = k + 1
if A[(i+di)%n][(j+dj)%n]:
di, dj = dj, -di
i += di
j += dj
return A
class Solution2(object):
"""
讨论区解法2,可以说很强大了
Runtime: 20 ms, faster than 100.00% of Python online submissions for Spiral Matrix II.
Memory Usage: 10.9 MB, less than 5.62% of Python online submissions for Spiral Matrix II.
"""
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
A = [[n*n]]
while A[0][0] > 1:
A = [range(A[0][0] - len(A), A[0][0])] + zip(*A[::-1])
return A
62. Unique Paths
class Solution(object):
"""
因为最后一步只有两种情况,要么从左到右,要么从上到下,所以可以去算前面两种情况的和
解法事先定义一个集合,每一种路径则在目的地+1,到最后的[-1][-1]即能找到最后的路径总数
Runtime: 16 ms, faster than 100.00% of Python online submissions for Unique Paths.
Memory Usage: 10.8 MB, less than 31.15% of Python online submissions for Unique Paths.
"""
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
res = [[1 for _ in range(m)] for _ in range(n)]
for i in range(1,n):
for j in range(1,m):
res[i][j] = res[i][j-1] + res[i-1][j]
return res[-1][-1]
class Solution(object):
"""
上面的优化!
Runtime: 16 ms, faster than 100.00% of Python online submissions for Unique Paths.
Memory Usage: 10.6 MB, less than 96.72% of Python online submissions for Unique Paths.
"""
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
dp = [1] + [0] * (n-1)
for i in range(m):
for j in range(1, n):
dp[j] += dp[j-1]
return dp[-1]
63. Unique Paths II
class Solution(object):
"""
直接按照62的解题思路来做
Runtime: 24 ms, faster than 61.86% of Python online submissions for Unique Paths II.
Memory Usage: 10.9 MB, less than 22.36% of Python online submissions for Unique Paths II.
"""
def uniquePathsWithObstacles(self, obstacleGrid):
"""
:type obstacleGrid: List[List[int]]
:rtype: int
"""
if not obstacleGrid or not obstacleGrid[0]:
return 0
m = len(obstacleGrid)
n = len(obstacleGrid[0])
dp = [[0]*n for _ in range(m)]
if obstacleGrid[0][0] == 0:
dp[0][0] = 1
else:
return 0
for i in range(m):
for j in range(n):
if obstacleGrid[i][j] == 1:
continue
if i > 0:
dp[i][j] += dp[i-1][j]
if j > 0:
dp[i][j] += dp[i][j-1]
return dp[-1][-1]
64. Minimum Path Sum
class Solution(object):
"""
题目容易和62、63弄混了,该题的意思是在给定的双重数组里,找出从gird[0][0]到grid[-1][-1]的最短距离
所以原理还是和unique path相差不大,即最短距离就是当前的位置+左边/上边的最短路径,依次推导便是了
即遍历两次,每次取左边或者上边的最小值,但要考虑两种特殊情况:第一行和第一列,因为他们各自没有上边和左边,
因此当row=0,直接取左边的值为最小值,col=0.取右边的值为最小值
Runtime: 32 ms, faster than 94.90% of Python online submissions for Minimum Path Sum.
Memory Usage: 11.8 MB, less than 53.62% of Python online submissions for Minimum Path Sum.
"""
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
m,n = len(grid),len(grid[0])
for row in range(m):
for col in range(n):
if row == col == 0:
before = 0
elif row == 0:
before = grid[row][col-1]
elif col == 0:
before = grid[row-1][col]
else:
before = min(grid[row-1][col],grid[row][col-1])
grid[row][col] = before + grid[row][col]
return grid[-1][-1]
总结
本次分享到此结束,谢谢~