菜鸡的一些力扣记录

入坑力扣,希望可以经常练一练,然后记录一下,更新。

所有一级标题的前缀为:leetcode-cn.com/problems

/container-with-most-water

第一次使用了暴力O(n^2)的方法,直接超出限制,后来改为O(n)。

Python

class Solution:
    def maxArea(self, height: List[int]) -> int:
        current_max_area = 0
        left = 0
        right = len(height)-1
        while right>left:
            area = (right-left)*min(height[left], height[right])
            if area > current_max_area:
                current_max_area = area
            if height[left] > height[right]:
                right -= 1
            else:
                left += 1
        return current_max_area

C

int maxArea(int* height, int heightSize){
    int current_max_area = 0;
    int area;
    int left = 0;
    int right = heightSize-1;
    while (right > left){
        if (height[left] > height[right]){
            area = (right-left)*height[right];
            right -= 1;
        }else{
            area = (right-left)*height[left];
            left += 1;
        }
        if (area > current_max_area){
            current_max_area = area;
        }
    }
    return current_max_area;
}

大佬ChengMing评论:这里用到了动态规划,基本的表达式: area = min(height[i], height[j]) * (j - i),使用两个指针,值小的指针向内移动,这样就减小了搜索空间。因为面积取决于指针的距离与值小的值乘积,如果值大的值向内移动,距离一定减小,而求面积的另外一个乘数一定小于等于值小的值,因此面积一定减小,而我们要求最大的面积,因此值大的指针不动,而值小的指针向内移动遍历。

/valid-sudoku/submissions/

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        rows = [[] for _ in range(0,9)]
        columns = [[] for _ in range(0,9)]
        squares = [[] for _ in range(0,9)]
        for i in range(0,9):
            for j in range(0,9):
                if board[i][j] != '.':
                    if board[i][j] in rows[i]:
                        return False
                    else:
                        rows[i].append(board[i][j])
                    if board[i][j] in columns[j]:
                        return False
                    else:
                        columns[j].append(board[i][j])
                    k1 = i//3
                    k2 = j//3
                    k = k1 + k2 * 3
                    if board[i][j] in squares[k]:
                        return False
                    else:
                        squares[k].append(board[i][j])
        return True

思路一:

  1. 对于每一行,检验是否有重复元素;
  2. 对于每一列,检验是否有重复元素;
  3. 对于每一个方格,检验是否有重复元素。

思路二(采用):

  1. 对每一行、每一列、每个方格建立一个列表,存储已经出现过的元素;
  2. 对矩阵中的各个元素依次扫描,查看其是否已在对应的行、列、方格中出现过;
  3. 如已曾出现返回false,如未出现将其加入。

/sudoku-solver

class Solution:
    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        def is_valid(i, j, s):
            k_row = i//3
            k_col = j//3
            b_square = []
            for k in range(0,3):
                b_square += board[3*k_row:3*k_row+3][k][3*k_col:3*k_col+3]
            if (s in board[i]) or (s in [b[j] for b in board]) or (s in b_square):
                return False
            return True
        
        def is_possible(position):
            if position == 81:
                return True
            i, j = position//9, position % 9
            if board[i][j] != '.':
                return is_possible(position+1)
            for k in range(0,9):
                s = str(k+1)
                if is_valid(i, j, s):
                    board[i][j] = s
                    if is_possible(position+1):
                        return True
                    else:
                        board[i][j] = '.'
            return False

        is_possible(0)

这个真写不出,以上代码参考自xyz

解数独思路:
对于所有未填充的格子,从1~9中选择数字,依次尝试填充,如果发现重复了,那么擦除,退回上一步,直到把整个数组填充完成。

重点在于这个退回过程的实现,实际上也就是所说的回溯。

/jump-game

解题思路:从后向前遍历元素,对于最后一个元素a,判断是否有前面的元素b可以跳到它。如果有,则问题转换为是否可以从开头跳到元素b,截断后面的元素;如果没有,输出False。

class Solution:
    def whichCanJump(self, nums, index):
        for i in range(0,index):
            j=index-i-1
            if nums[j]+j>=index:
                return j
        return index

    def canJump(self, nums: List[int]) -> bool:
        l = len(nums)
        current = l-1
        while current!=0:
            lastStep = self.whichCanJump(nums,current)
            if lastStep==current:
                return False
            else:
                current = lastStep
        return True

/spiral-matrix

思路:记录上下左右边界所在的位置,依次循环输出上、右、下、左的元素,但是遇到一些错误,因此做了一些修正。

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        data=[]
        up=0
        left=0
        down=len(matrix)-1
        right=len(matrix[0])-1
        while True:
            data+=matrix[up][left:right]
            data+=[matrix[i][right] for i in range(up,down)]
            data+=matrix[down][right:left:-1]
            data+=[matrix[i][left] for i in range(down,up,-1)]
            up+=1
            down-=1
            left+=1
            right-=1
            if up>down:
                break
            if left>right:
                break
        #弥补第一种情况[[1,2,3],[4,5,6],[7,8,9]]
        if len(data)<len(matrix)*len(matrix[0]):
            data.append(matrix[up-1][left-1])
        #弥补第二种情况[[1,2,3,4,5,6,7,8,9]]
        while len(data)>len(matrix)*len(matrix[0]):
            data.pop()
        return data
原文地址:https://www.cnblogs.com/dingdangsunny/p/15225101.html