哈希表
lc 283. 移动零
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
cnt = 0
i = 0
while i!=len(nums):
if nums[i] == 0:
cnt+=1
nums.pop(i)
else:
i+=1
for i in range(cnt):
nums.append(0)
- 和贪心那一样,是pop,remove和while的妙用,
lc 566. 重塑矩阵
reshape 的操作,如果给的r和c乘不回去,返回原来的mat
class Solution:
def matrixReshape(self, mat, r: int, c: int):
tmp = []
res = []
for i in mat:
tmp.extend(i)
length = len(tmp)
if r * c != length:
return mat
else:
for row in range(r):
tmp_in = []
for col in range(c):
v = tmp.pop(0)
tmp_in.append(v)
res.append(tmp_in)
return res
lc 485. 最大连续 1 的个数
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
cnt = 0
res = 0
for i in nums:
if i!=0:
cnt+=1
else:
res = max(res,cnt)
cnt = 0
# 给最后一次
res = max(res,cnt)
return res
lc 240. 搜索二维矩阵 II
class Solution:
def searchMatrix(self,martix:List[List[int]],target:int):
row = 0
col = len(martix[0])-1
while row<=len(martix)-1 and col>=0:
if target < martix[row][col]:
col-=1
elif target > martix[row][col]:
row+=1
else:
return True
return False
- 最右上角的点最重要,往左是减小,往下是增加。
- 因为是从该特殊点开始遍历,注意是遍历,所以不会有遗漏。
lc 378. 有序矩阵中第 K 小的元素
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
def count_num(mat,val):
row = 0
col = len(mat) - 1
cnt = 0
while row<len(mat) and col>=0:
if mat[row][col]<=val:
# 重点1
cnt+=col+1
row+=1
else:
col-=1
return cnt
left = matrix[0][0]
right = matrix[-1][-1]
while left<right:
mid = (left+right)//2
cnt = count_num(matrix,mid)
if cnt<k:
left = mid+1
else:
# 重点2
right = mid
return left
- 变相有序,想找第k个元素,二分。
- 重点1:用col走,因为遍历,所以cnt是变化可以追溯的,而且它下面是联动的。
- 重点2:不在范围所以left+1,但是等于的时候是mid,因为相当于不在就移动。
- 更重要的是这left和right是表中的数,不是index。通过数找到index。
lc 645. 错误的集合
class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
sum_nodup=sum(set(nums))
n = len(nums)
miss = sum(nums) - sum_nodup
dup = n*(n+1)//2 - sum_nodup
return [miss,dup]
- 用数学的思路解很简单,因为是从1开始只会多一个数,所以miss很显然。多的那个则是需要运算一下,不能是miss+1会出错,比如[2,2]。
lc 287. 寻找重复数
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
slow = nums[0]
fast = nums[nums[0]]
while (slow != fast):
slow = nums[slow]
fast = nums[nums[fast]]
fast = 0
while (slow != fast):
slow = nums[slow]
fast = nums[fast]
return slow
- 链表快慢指针找环形入口。
- 为啥这样能表示快慢指针?
lc 667. 优美的排列 II
给一个n和k,要求那个数前后之差有k个不一样(至少)。
class Solution:
def constructArray(self, n: int, k: int) -> List[int]:
res = list(range(1,n-k+1))
f,d = 1,k
# 构造k个不一样,这样编排正好是k个不一样还都在n范围内
for i in range(k):
res.append(res[-1]+f*d)
f = -f
d -= 1
return res
- 一个纯数学构造问题,真的是撑得出这个题还有上面的题。
lc 697. 数组的度
# 推荐
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
res = {}
max_degree = 0
for index,i in enumerate(nums):
if i not in res:
res[i] = [index,index,1]
else:
res[i][1] = index
res[i][2] +=1
max_degree = max(max_degree,res[i][-1])
need = float('inf')
for k,v in res.items():
if v[-1]==max_degree:
need = min(need,v[1]-v[0]+1)
return need
# 受到前面的题目启发
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
degree = {}
length = {}
max_degree = 0
for index,i in enumerate(nums):
length[i] = index
if i not in degree:
degree[i] = 1
else:
degree[i]+=1
max_degree = max(max_degree,degree[i])
need_nums = []
for k,v in degree.items():
if v == max_degree:
need_nums.append(k)
res_min = float('inf')
for i in need_nums:
res_min = min(res_min,length[i]-nums.index(i)+1)
return res_min
- 其实两种解法一样,第一个因为数据结构优化所以更快,遍历少,但是第二个凸显本质,就是说找到度最小,记录每一个数字的最后一次的位置,在从头遍历一次去相减。
lc 565. 数组嵌套
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
n = len(nums)
waslooked = [1]*n
res = 0
for i in nums:
if waslooked[i]:
cnt = 1
index = nums[i]
waslooked[i]=0
while i != index:
index = nums[index]
cnt+=1
waslooked[i]=0
res=max(res,cnt)
return res
- 走过的就不再走了,因为前面走过的肯定比后面成环的大,不用再走一遍。
- 这样的类似的题目都是 i==index,固定i滚动index。
lc 769. 最多能完成排序的块
class Solution:
def maxChunksToSorted(self, arr: List[int]) -> int:
cur_max=float('-inf')
count = 0
for i,val in enumerate(arr):
cur_max = max(cur_max,val)
if cur_max <= i:
count+=1
return count
lc 766. 托普利茨矩阵
class Solution:
def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
def check(matrix,expcet_val,row,col):
if row >= len(matrix) or col>=len(matrix[0]):
return True
if matrix[row][col]!=expcet_val:
return False
return check(matrix,expcet_val,row+1,col+1)
rows = len(matrix)
cols = len(matrix[0])
for i in range(rows):
if not check(matrix,matrix[i][0],i,0):
return False
for j in range(cols):
if not check(matrix,matrix[0][j],0,j):
return False
return True
- 递归的往下走。