矩阵置零
给定一个 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