leetcode数组, python实现

矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

示例 1:

输入: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

示例 2:

输入: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]

]
进阶:

1、一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
2、一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
3、你能想出一个常数空间的解决方案吗?

方法1、最坏情况都为0,需要O(m*n)的空间。随0 而变
解析:1、遍历矩阵,将每个0的坐标存入stack后,依次pop()
2、将pop出的坐标,对矩阵进行横、纵方向都清0

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        if matrix == [[]]:
            return 
        if len(matrix) == 1:
            if 0 in matrix:
                matrix = [[0]*len(matrix)]
    # 保存 == 0 的坐标
        stack = []
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    stack.append([i, j])
   		# 出栈
        while stack:
            x, y = stack.pop(0)
            # 整列清0
            for index1 in range(len(matrix)):
                matrix[index1][y] = 0
              # 整行清0
            for index2 in range(len(matrix[0])):
                matrix[x][index2] = 0

方法2、m+n的办法,开辟两个数组,一个保存横坐标,一个保存纵坐标。
最坏(每行、每列都会被清0)O(m+n),最好情况就是O(1)。

 注: 并非严格的O(m+n),两个列表中的元素,分别都会重复

解析:1、列表1保存横坐标, 列表2保存纵坐标。遍历矩阵,当matrix==0的点的i, j都不在两个列表中时,将该点加入
2、之后pop, x, y 同时分别接收, 列表1和列表2的pop

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        if matrix == [[]]:
            return
        if len(matrix) == 1:
        # 不知道为什么这里matrix[0]得不到想要的结果
            if 0 in matrix:
                matrix = [[0]*len(matrix)]
        
        L1 = [] # 保存横坐标
        L2 = [] # 保存纵坐标
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                # 如果横纵坐标都分别在数组中,即该行和列都会被某一点清0,下一个
                    if i in L1 and j in L2:
                        continue
                     # 行或者列不再,都要将两者送入
                    else:
                        L1.append(i)
                        L2.append(j)
        while L1:
        # 同时pop出x,y,可能某一个清0操作会重复
            x = L1.pop(0)
            y = L2.pop(0)
            for i in range(len(matrix)):
                matrix[i][y] = 0
            for j in range(len(matrix[0])):
                matrix[x][j] = 0

方法2:
严格O(m+n), 行或列没有时候, 加入没有的元素,存在的就不再存入列表中

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        if matrix == [[]]:
            return
        if len(matrix) == 1:
            if 0 in matrix:
                matrix = [[0]*len(matrix)]
        
        L1 = []
        L2 = []
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    if i in L1 and j in L2:
                        continue
                    elif i not in L1 and j in L2:
                        L1.append(i)
                    elif i in L1 and j not in L2:
                        L2.append(j)
                    else:
                        L1.append(i)
                        L2.append(j)
        while L1:
            x = L1.pop(0)
            # 行清0
            for j in range(len(matrix[0])):
                matrix[x][j] = 0
        while L2:
            y = L2.pop(0)
            # 行清0
            for j in range(len(matrix)):
                matrix[j][y] = 0

无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 

解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1

解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3

解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
思路: 开辟一个temp列表来保存连续无重复字符串长度。O(N^2)

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if len(s) <= 1:
            return len(s)
        
        MAX = 0
        for i in range(len(s)-1):
            temp = [s[i]]
            for j in range(i+1, len(s)):
                if s[j] not in temp:
                    temp.append(s[j])
                else:
                    break
            MAX = max(MAX, len(temp))
            if MAX >= len(s)-i-1:
                break
        return MAX

最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"

注意: “aba” 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

我:
O(n^2)的做法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s)<=1:
            return s
        if s == s[::-1]:
            return s
        MAX = 1
        # 如果没有更长的回文子串,返回s[0]
        result = s[0]
        for i in range(len(s)-1):
        # 从s[i]开始记录
            temp = s[i]
            for j in range(i+1, len(s)):
                temp += s[j]
                # 记录当前最大长度
                if temp == temp[::-1]:
                    if len(temp) > MAX:
                        MAX = len(temp)
                        result = temp
                # 当前不是回文字符串,不代表再增加后不是,继续循环
                else:
                    continue
             如果当前长度大于接下来可能出现的最大长度,终止循环
            if MAX > len(s) - 1:
                break
        return result

递增的三元子序列

给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。

数学表达式如下:

如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,
使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。

说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。

示例 1:

输入: [1,2,3,4,5]
输出: true

示例 2:

输入: [5,4,3,2,1]
输出: false

解析:1、 额外定义一个长度为2的额外数组空间,初始状态二者都是无穷大
2、循环遍历数组,将当前最小的数放在额外空间的第一位。将比它大的放在res[1]
,当出现比res[1]大的数时。此时就有三个递增元子

class Solution:
    def increasingTriplet(self, nums: List[int]) -> bool:
        if len(nums) < 3:
            return False
        res = [float('inf'), float('inf')]
        
        for num in nums:
        # 初始情况不会存在比无限大更大的值,所以存在该值时一定可以返回True
            if num > res[1]:
                return True
             # 相当于[0] 位置存放当前最小值
            if num < res[0]:
                res[0] = num
           # 比【0】大,则放在[1]的位置     
            if num > res[0]:
                res[1] = num
        return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值