Leetcode题medium48/54/55/56/59/62/63/64,Python多种解法(四)

前文

  继上一篇,[Leetcode题medium11/15/16/18/31/33/34/39/40,Python多种解法(三)(https://blog.csdn.net/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]

总结

  本次分享到此结束,谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值