leetcode 第54、59、61题 Python

54. 螺旋矩阵

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
思路1:设置四种case,观察到第一种case是行不变列一直在变,第二种case的列数不变行数变,以此类推。

并且可以发现规律,第一次遍历的个数等于列数,第二次遍历的个数等于行数减一,第三次等于列数减一,第四次等于行数再减一。。。

case表明是哪一种情况,0对应向右, 1对应向下,2 对应向左,3对应向上
ri, ci 表示我们当前遍历的点的位置坐标。
row, col, 用来代表这一次运动的步数。我们用它们可以组合出下一次终点的坐标。举例,若是case0向右运动,所以(ri, ci + col)就是运动末位置的后一项。注意到每次运动的步数都逐步减少,发现规律:当你移完横向运动类型的运动后,row -= 1;而竖的运动(case 1 3), col -= 1。然后每一次case结尾更新ri, ci也即此次运动的末尾坐标和下一次开始的起始坐标。
思路2:考虑好边界问题。
首先定义方向:向下表示y正方向,向右表示x正方向。我们再定义两个点,分别是左上x1,y1和右下x2,y2,这样每循环一次将x1++,y1++并且x2–,y2–。
对于top箭头,采用[x1,x2]这个区间。对于right这个箭头,采用(y1,y2]这个区间。对于down这个箭头,采用(x2,x1)这个区间(注意,这里的区间定义和数学上有区别)。对于left这个箭头,采用[y2,y1)这个区间。对于循环的结束条件,定义为x1<=x2 and y1<=y2,但是这个时候要单独考虑(x2,x1)这个区间,要限定x1<x2 and y1<y2。对于[y2,y1)这个区间也要做相同的限定x1<x2,为什么呢?因为当x1==x2的时候实际上只有一列要输出,而在right中已经输出了,所以此时没有必要在此输出。

class Solution:
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """
        def cyc(row, column, ri, ci, case):
            #递归终止条件
            if row == 0 or column == 0:
                return
            #第一种case,横着走
            if case == 0:
                #结束的位置的column
                endci = ci + column
                for i in range(ci, endci):
                    #添加元素
                    re.append(matrix[ri][i])
                #横移后row的长度减一
                row -= 1
                ri += 1
                ci = endci-1
                #我们想让case 不断增加但在0-4内循环
                case = (case + 1)%4
                cyc(row, column, ri, ci, case)
 
            elif case == 1:
                endri = ri + row
                for i in range(ri, endri):
                    re.append(matrix[i][ci])
                column -= 1
                ci -= 1
                ri = endri-1
                case = (case+1)%4
                cyc(row, column, ri, ci, case)
 
            elif case == 2:
                endci = ci - column
                for i in range(ci, endci, -1):
                    re.append(matrix[ri][i])
                row -= 1
                ri = ri - 1
                ci = endci + 1
                case = (case+1)%4
                cyc(row, column, ri, ci, case)
 
            elif case == 3:
                endri = ri - row
                for i in range(ri, endri, -1):
                    re.append(matrix[i][ci])
                column -= 1
                ri = endri + 1
                ci = ci + 1
                case = (case+1)%4
                cyc(row, column, ri, ci, case)
 
        re = []
        row = len(matrix)
        if row == 0:
            return []
        column = len(matrix[0])
        cyc(row, column, 0, 0, 0)
        return re
class Solution:
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """
        result = list()
        if not matrix:
            return result
        r, c = len(matrix), len(matrix[0])        
        x1, y1, x2, y2 = 0, 0, c-1, r-1
        while x1 <= x2 and y1 <= y2:
            for i in range(x1, x2+1):
                result.append(matrix[y1][i])

            for j in range(y1+1, y2+1):
                result.append(matrix[j][x2])
            if x1 < x2 and y1 < y2:
                for i in range(x2-1, x1, -1):
                    result.append(matrix[y2][i])

                for j in range(y2, y1, -1):
                    result.append(matrix[j][x1])
            
            x1 += 1
            y1 += 1
            x2 -= 1
            y2 -= 1

        return result

59. 螺旋矩阵 II

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

class Solution:
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        result = [[0]*n for _ in range(n)]
        x1, y1, x2, y2, k = 0, 0, n-1, n-1, 1
        while x1 <= x2 and y1 <= y2:
            for i in range(x1, x2+1):
                result[y1][i] = k
                k += 1
          
            for j in range(y1+1, y2+1):
                result[j][x2] = k
                k += 1

            if x1 < x2 and y1 < y2:
                for i in range(x2-1, x1, -1):
                    result[y2][i] = k
                    k += 1

                for j in range(y2, y1, -1):
                    result[j][x1] = k
                    k += 1
            
            x1 += 1
            y1 += 1
            x2 -= 1
            y2 -= 1

        return result

通过顺时针的操作将数都填到数组中。

class Solution:
    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 range(1,n**2+1):
            A[i][j] = k  
            if A[(i+di)%n][(j+dj)%n]:
                di, dj = dj, -di

            i += di
            j += dj
            
        return A 

61. 旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。

class Solution:
    def rotateRight(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        if head == None or head.next == None:
            return head

        pre = head
        count = 1
        while pre.next != None:
            count += 1
            pre = pre.next

        pre.next = head
        n = count - k%count
        q = pre

        for _ in range(n):
            q = q.next

        ret = q.next
        q.next = None
        return ret
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值