看了好多攻略,打算第一遍刷题顺序跟着 代码随想录 :数组、链表、哈希表、字符串、双指针法、栈与队列、二叉树、回溯算法 、贪心算法、动态规划、单调栈
题外话:小白一枚,打算刷题提高编程能力,由于现在在公司算法部门实习,所以使用python语言,打算明年秋招之前用java或者c++再刷一遍。下面纯记录个人刷题日记及代码。
两个月过去了……没刷几题,寒假回家躺平了,最近开始正式刷题了,看看能不能找到暑期实习吧,不打算学java了,还是老老实实冲算法吧!
代码随想录:代码随想录 (programmercarl.com)
704. 二分查找 - 力扣(LeetCode)
class Solution1:
def search(self, nums, target):
left, right = 0, len(nums) - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] < target:
left = middle + 1
elif nums[middle] > target:
right = middle - 1
else:
return middle
return -1
emp1 = Solution1()
emp1.search([-1,3,5,7,9,14,55,48],55)
#输出:6
class Solution3:
def search(self, nums, target):
left, right = 0, len(nums) - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] < target:
left = middle + 1
elif nums[middle] > target:
right = middle - 1
else:
return middle
return right + 1
emp3 = Solution3()
emp3.search([-1,3,5,7,9],8)
#输出:4
class Solution4:
def search(self, nums, target):
def result(nums,target):
left, right = 0, len(nums) - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] < target:
left = middle + 1
elif nums[middle] > target:
right = middle - 1
else:
return left
return -1
index = result(nums,target)
if index==-1:return [-1,-1]
left,right=index,index
while left -1 >=0 and nums[left - 1] == target: left -=1
while right+1 < len(nums) and nums[right + 1] == target:right +=1
print([left,right])
emp4 = Solution4()
nums=[-1,3,5,6,7,9,9,9,9,9]
target=9
emp4.search(nums,target)
#输出:[5,9]
方法一:
class Solution5:
def mySqrt(self, x: int) -> int:
l, r, ans = 0, x, -1
while l <= r: #不能漏掉l=r的情况
mid = (l + r) // 2
if mid * mid <= x:
ans = mid
l = mid + 1
else:
r = mid - 1
return ans
emp5 = Solution5()
emp5.mySqrt(9)
#输出:3
方法二:
class Solution6:
def mySqrt(self, x):
if x == 0:
return 0
x0,C = float(x),float(x)
while True:
xi = 0.5 * (x0 + C/x0)
if abs(x0 - xi) < 1e-7:
break
x0 = xi
return int(x0)
emp6 = Solution6()
emp6.mySqrt(10)
#输出:3
方法一:双指针法,快指针、慢指针
class Solution8:
def removeElement(self, nums,val):
fast = 0
slow = 0
for fast in range(len(nums)):
if nums[fast] == val:
continue
else:
nums[slow] = nums[fast]
slow +=1
return slow
emp8 = Solution8()
nums=[3,2,2,3]
val = 3
length=emp8.removeElement(nums,val)
for i in range(length):
print(nums[i])
#输出:2
# 2
方法二:双指针法、左指针、右指针
class Solution9:
def removeElement(self, nums,val):
right = len(nums)-1
left = 0
while left <= right:
if nums[left] == val:
nums[left] = nums[right]
right -= 1
else:
left += 1
return nums[0:left]
emp9 = Solution9()
nums=[3,2,2,2,3,6,7,5,3]
val = 2
emp9.removeElement(nums,val)
#输出:[3, 3, 5, 7, 3, 6]
class Solution10:
def removeDuplicates(self, nums):
fast = 1
slow = 0
for fast in range(len(nums)):
if nums[fast] == nums[slow]:
fast +=1
else:
slow +=1
nums[slow] = nums[fast]
return nums[0:slow]
emp10 = Solution10()
nums=[3,2,2,2,3,6,7,5,3]
emp10.removeDuplicates(nums)
#输出:[3, 2, 3, 6, 7, 5]
class Solution11:
def moveZeroes(self, nums):
right = 0
left = 0
for right in range(len(nums)):
if nums[right]:
nums[left],nums[right] = nums[right],nums[left]
left += 1
right +=1
return nums
emp11 = Solution11()
nums=[3,0,2,0,3,6,0]
emp11.moveZeroes(nums)
#输出:[3, 2, 3, 6, 0, 0, 0]
class Solution12:
def backspaceCompare(self,s,t):
def build(str):
ret = list()
for i in str:
if i != '#':
ret.append(i)
elif ret:
ret.pop() #保证ret里面有字符才能pop
return ret
return build(s) == build(t)
emp12 = Solution12()
s='a##c'
t='#a#c'
emp12.backspaceCompare(s,t)
#输出:True
方法一:直接排序
class Solution13:
def sortedSquares(self, nums):
return sorted(num * num for num in nums)
emp13 = Solution13()
nums=(2,3,4,7,8,-1,-3)
emp13.sortedSquares(nums)
#输出:[1, 4, 9, 9, 16, 49, 64]
方法二:双指针法,重点是有序数组,最大值是最右边或者最左边、左右指针
class Solution14:
def sortedSquares(self, nums):
n = len(nums)
result = [-1]*n
i,j,k = 0,n-1,n-1
while i <= j:
lm = nums[i]**2
rm = nums[j]**2
if lm > rm:
result[k] = lm
i +=1
else:
result[k] = rm
j -=1
k -=1
return result
emp14 = Solution14()
nums=(-3,-1,0,4,6,9)
emp14.sortedSquares(nums)
#输出:[0, 1, 9, 16, 36, 81]
滑动窗口、双指针法
class Solution15:
def minSubArrayLen(self, nums,target):
res = float("inf") #设为无穷大
sum = 0
i = 0
for j in range(len(nums)):
sum += nums[j]
while sum >= target:
res = min(res,j-i+1)
sum -= nums[i]
i += 1
if res == float("inf"):
return 0
else:
return res
emp15 = Solution15()
nums = (2,3,1,2,4,3)
target = 7
emp15.minSubArrayLen(nums,target )
#输出:2
class Solution16:
def totalFruit(self, fruits: List[int]) -> int:
ans = i = 0
count = collections.Counter()
for j, x in enumerate(fruits):
count[x] += 1
while len(count) >= 3:
count[fruits[i]] -= 1
if count[fruits[i]] == 0:
del count[fruits[i]]
i += 1
ans = max(ans, j - i + 1)
return ans
emp16 = Solution16()
fruits = (2,3,1,2,2,1,3)
emp16.totalFruit(fruits)
#输出:4
双休 没学
76. 最小覆盖子串
这个对我来说有点困难啊啊啊
首先是我不懂enumerate返回的是什么类型的数据,然后测试了下:
s = "ADOBECODEBANC"
print(list(enumerate(s)))
for j,c in enumerate(s):
print(j,c)
用了滑窗方法,借鉴了力扣里面大佬的题解思路,官方题解没有python版本
滑动窗口思想 - 最小覆盖子串 - 力扣(LeetCode)
class Solution17:
def minWindow(self, s: str, t: str) -> str:
need = collections.defaultdict(int)
for c in t:
need[c] += 1 #记录了遍历到的所有元素,而只有need[c]>0时,代表c就是所需元素
needCnt = len(t) #记录所需元素的总数量
i = 0 #记录起始位置
res = (0, float('inf')) #用两个元素,方便之后记录起终点
#三步骤:
#1. 增加右边界使滑窗包含t
for j,c in enumerate(s):
if need[c] >0:
needCnt -= 1
need[c] -= 1 #这行放在外面不可以,看19行 need[c] == 0
#2. 收缩左边界直到无法再去掉元素 !注意,处理的是i
if needCnt == 0:
while True:
c = s[i]
if need[c] == 0: #表示再去掉就不行了(need>0)
break
else: #need里面<0的都是不需要的,将他们+1,且去掉,滑窗右移
need[c] += 1
i += 1
#if j-i < res[1] - res[0]: #这里是否减一都可以,只要每次都是这样算的就行,反正最后也是输出子串而非长度
res = (i,j)
#3. i多增加一个位置,准备开始下一次循环(注意这步是在 needCnt == 0里面进行的 )
need[s[i]] += 1
needCnt += 1 #由于 移动前i这个位置 一定是所需的字母,因此NeedCnt才需要+1
i += 1
return s[res[0]: res[1]+1]
emp17 = Solution17()
s = "ADOBECODEBANC"
t = "ABC"
emp17.minWindow(s,t)
#输出:'BANC'
困难程度的题对我来说确实是困难,花了5个小时才勉强看懂算法思路,过段时间估计又忘了……
class Solution19:
def generateMatrix(self, n: int) -> [[int]]:
l, r, t, b = 0, n - 1, 0, n - 1
mat = [[0 for _ in range(n)] for _ in range(n)]
num, tar = 1, n * n
while num <= tar:
for i in range(l, r + 1): # left to right
mat[t][i] = num
num += 1
t += 1
for i in range(t, b + 1): # top to bottom
mat[i][r] = num
num += 1
r -= 1
for i in range(r, l - 1, -1): # right to left
mat[b][i] = num
num += 1
b -= 1
for i in range(b, t - 1, -1): # bottom to top
mat[i][l] = num
num += 1
l += 1
return mat
emp19 = Solution19()
n = 3
emp19.generateMatrix(n)
#输出:[[1, 2, 3], [8, 9, 4], [7, 6, 5]]
方法二:需要额外考虑中心数,边界用左右和上下共同约束,都是左闭右开区间
class Solution20:
def generateMatrix(self, n: int) -> [[int]]:
left,right,up,down = 0,n-1,0,n-1
number = 1
mat = [[0]*n for _ in range(n) ]
while left < right and up < down:
for i in range(left,right):
mat[up][i] = number
number += 1
for j in range(up,down):
mat[j][right] = number
number += 1
for i in range(right,left,-1):
mat[down][i] = number
number += 1
for j in range(down,up,-1):
mat[j][left] = number
number += 1
left += 1
right -= 1
up += 1
down -= 1
# 如果阶数为奇数,额外填充一次中心
if n % 2:
mat[n // 2][n // 2] = number
return mat
emp20 = Solution20()
n = 3
emp20.generateMatrix(n)
#输出:[[1, 2, 3], [8, 0, 4], [7, 6, 5]]
两种方法用了不同的初始化0矩阵的方法
逆向推还是推不出来,我太菜了
方法一:根据上题方法二改动的
还是没明白为啥while循环体内还要嵌套个if判断条件,整不明白
class Solution22:
def spiralOrder(self, matrix):
if not matrix or not matrix[0]:
return list()
ans = []
rows, columns = len(matrix), len(matrix[0])
left,right,up,down = 0,columns - 1,0,rows - 1
while left <= right and up <= down:
for i in range(left,right + 1):
ans.append(matrix[up][i])
for j in range(up + 1,down + 1):
ans.append(matrix[j][right])
if left < right and up < down: #就是这里不明白
for i in range(right - 1,left,-1):
ans.append(matrix[down][i])
for j in range(down,up,-1):
ans.append(matrix[j][left])
left += 1
right -= 1
up += 1
down -= 1
return ans
emp22 = Solution22()
matrix = [[1, 2, 3], [4,5,6], [7, 8,9]]
emp22.spiralOrder(matrix)
#输出:[1, 2, 3, 6, 9, 8, 7, 4, 5]
方法二:我是看不懂的,python这语法我都看不懂了,只知道这个方法好像很厉害的样子
class Solution21:
def spiralOrder(self, matrix):
ans = []
while matrix:
ans += matrix.pop(0) # 向右
if matrix and matrix[0]:
ans += [row.pop(-1) for row in matrix] # 向下
else: return ans
if matrix: ans += matrix.pop(-1)[::-1] # 向左
else: return ans
if matrix and matrix[0]: ans += [row.pop(0) for row in matrix][::-1] # 向上
else: return ans
return ans
emp21 = Solution21()
matrix = [[1, 2, 3], [4,5,6], [7, 8,9]]
emp21.spiralOrder(matrix)
#输出:[1, 2, 3, 6, 9, 8, 7, 4, 5]