leetcode
时间复杂度、空间复杂度
- 大O就是数据量级突破一个点且数据量级非常大的情况下所表现出的时间复杂度,这个数据量也就是常数项系数已经不起决定性作用的数据量。
- O(1)常数阶 < O ( log n ) O(\log n) O(logn)对数阶 < O ( n ) O(n) O(n)线性阶 < O ( n 2 ) O(n^2) O(n2)平方阶 < O ( n 3 ) O(n^3) O(n3)立方阶 < O ( 2 n ) O(2^n) O(2n)指数阶
每日练习
717. 1比特与2比特字符(2.20)
- 从起点开始遍历,当遇到1时,这个1一定会把下一个0或1吃掉,需跳过下一个。如果能遍历到最后一个0,就 return True。
- 两个条件:
- 遇到1,i += 2;
- 遇到0,如果为最后一个字符,return True,否则 i += 1。
class Solution:
def isOneBitCharacter(self, bits: List[int]) -> bool:
i = 0
while i < len(bits):
if bits[i] == 1:
i += 2
else:
if i == len(bits)-1:
return True
i += 1
return False
数组
704. 二分查找
注意:
-
//整除,向下取整;
-
<= 对应 +1,-1 闭区间
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)-1
while left <= right:
mid = (left + right) // 2 #向下取整
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
return -1
27. 移除元素
-
双指针就是数字下标,字符串只能覆盖。先让fast指针在前面寻找并跳过val,然后将非val赋值给slow,覆盖掉val。
-
循环边界要注意,slow属于fast中间的一个条件(大包小)。
题目:
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow = fast = 0
while fast < len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
977.有序组的平方
-
双指针:一个指开头,一个指结尾。还要创建一个字符串 new[]。
-
循环结束条件:指结尾的指针 < 指开头的指针
题目:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
i, j, k = 0, len(nums)-1, len(nums)-1
new = [0] * len(nums)
while j >= i:
if nums[i]*nums[i] > nums[j]*nums[j]:
new[k] = nums[i] * nums[i]
i += 1
else:
new[k] = nums[j] * nums[j]
j -= 1
k -= 1
return new
209. 长度最小的子数组
- k = float(inf) 表示无穷大的数
- range(6) 表示0-6
- 滑动窗口、双指针:数组和>=target的情况都要放到while里,因此index差要+1
题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
i = Sum = 0
k = float(inf) #无穷大
if sum(nums) < target: return 0
for j in range(len(nums)):
Sum = Sum + nums[j]
while Sum >= target: #和>=情况都需考虑
k = min(k, j-i+1) #需要+1
Sum = Sum - nums[i]
i += 1
return k
904. 水果成篮
- 滑动窗口,先用一个basket放可装进的种类,超过2个就用 .remove()去掉淘汰的种类,不能用 .pop(),因为第一个可能是需要的种类。
- 在超过2个种类的情况中,左边的指针要先减2,判断是否还会有重复的值,若没有,再加一。
题目:
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
你只有**两个 ** 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
输入:fruits = [0,1,2,2]
输出:3
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
i = 0
basket = [fruits[0]]
sum = 0
for j in range(len(fruits)):
if fruits[j] not in basket:
basket.append(fruits[j])
if len(basket) > 2:
i = j - 2
while fruits[i] == fruits[j-1]:
i -= 1
basket.remove(fruits[i])
i += 1
sum = max(sum, j-i+1)
print(basket)
return sum
59. 螺旋矩阵 ||
- 选择左闭右开,例如:12,34,56,78。设置up,down,right,left四边,第二轮及之后的更改较为方便
- range(1,5) -->1,2,3,4 ; range可以递减,但需要在最后-1
- 若为奇数,需要把中间的单独拎出来
题目:
![image-20220222105818461](/Users/hu/Library/Application%20Support/typora-user-images/image-20220222105818461.png)
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
mt = [[0] * n for _ in range(n)] #设置矩阵[[]]
count = 1
loop = n//2 #向下取整
up, down, right, left = 0, n-1, n-1, 0
while loop > 0:
for x in range(left, right):
mt[up][x] = count
count += 1
for y in range(up, down):
mt[y][right] = count
count += 1
for x in range(right, left, -1):
mt[down][x] = count
count += 1
for y in range(down, up, -1):
mt[y][left] = count
count += 1
loop -= 1
up = up + 1
right = right-1
down = down - 1
left = left + 1
if n%2 == 1:
mt[n//2][n//2] = n*n
return mt