239. Sliding Window Maximum(Leetcode每日一題-2021.01.02)--抄答案
時間複雜度
- 線性時間複雜度演算法
- 單調棧
- 字首和
- 差分陣列
- 雙指標
- 滑動視窗
排序
桶排序
max_, min_ = max(nums), min(nums) bucket_len = max(1, (max_ - min_) // (n - 1)) # 確定桶的長度 最小為1 bucket_num = (max_ - min_) // bucket_len + 1 # 確定桶的數量 要加一 buckets = [[] for _ in range(bucket_num)] # 初始化所有桶 for num in nums: # 將所有元素新增到桶內 buckets[(num - min_) // bucket_len].append(num)
歸併排序
將陣列分為兩個子陣列,子陣列各自排序後再合併
leetcode-493 翻轉對
def merge(nums, lo, mid, hi): # 合併兩個排序好的陣列 aux = nums[lo : hi + 1] # 備份 儲存原始值 i, j = lo, mid + 1 # 左右兩個子陣列的起點 for k in range(lo, hi + 1): if (i > mid): # 左邊陣列已經全部合併 nums[k] = aux[j - lo] j += 1 elif (j > hi): # 右邊陣列已經全部合併 nums[k] = aux[i - lo] i += 1 elif aux[i - lo] < aux[j - lo]: nums[k] = aux[i - lo] i += 1 else: nums[k] = aux[j - lo] j += 1 def merge_sort(nums, lo, hi): # 歸併排序 包括lo到hi的全部數字 列表表示應該是range(lo, hi+1) if lo < hi: mid = (lo + hi) // 2 merge_sort(nums, lo, mid) merge_sort(nums, mid+1, hi) merge(nums, lo, mid, hi)
二分
回溯
leetcode-90 子集Ⅱ:集合去重
leetcode-842 將陣列拆分乘斐波那契序列
位運算
a = a << 1 # 左移
a = a >> 1 # 右移
a = a & b # 與
a = a | b # 或
a = a ^ b # 異或 若a等於b^c 則有b等於a^c
~a # 非
數論
計算排列組合
def C(total, t): ans = 1 for i in range(1, t + 1): ans = ans * (total - i + 1) // i return ans
快速冪
時間複雜度O(logN)。
leetcode-50 Pow(x,n)
def myPow(x, n): # 計算x^n n>=0
ans = 1.0
x_contribute = x
while n > 0:
if n % 2 == 1:
ans = ans * x_contribute
x_contribute *= x_contribute
n = n // 2
return ans
線性篩
O(n)時間複雜度內找到小於n的素數。
leetcode-204 計數質數
def countPrimes(n):
is_prime = [1] * n # 判斷當前數字是否為素數
is_prime[0] = is_prime[1] = 0
primes = []
for i in range(2, n):
if is_prime[i]:
primes.append(i)
for prime in primes:
if prime * i < n:
is_prime[prime * i] = 0
if i % prime == 0: break # 後面的數一定可以被prime篩到 退出迴圈
else: break # 後面的素數*i也一定大於n 退出迴圈
return len(primes)
動態規劃
leetcode-53 最大子序和
leetcode-188 買賣股票的最佳時機IV
狀態dp
leetcode-5619 最小不相容性
字串
找回文子串
動態規劃O(N^2 ),中心擴充套件O(N^2 ),Manacher演算法(N)
leetcode-5 最長迴文子串
資料結構
優先佇列
能夠完成下列操作的資料結構叫做優先佇列:
(1)插入一個數值
(2)取出最小的數值(獲得數值,並且刪除)
使用堆來進行解決,準確的說是二叉堆。
leetcode-1046 最後一塊石頭的重量
棧
leetcode-402 移掉K位數字
leetcode-316 去除重複字母
單調棧
線性時間複雜度下,維護一個單調遞增或者遞減的棧。
在原始順序下,針對每一個元素找到下一個恰好大於或小於它的元素。
leetcode-42 接雨水
leetcode-84 柱狀圖中的最大矩形
leetcode-85 最大矩形
leetcode-321 拼接最大數
leetcode-5614 找出最具競爭力的子序列
leetcode-239 滑動視窗最大值
stack = []
heights = [0] + heights + [0] # 處理好邊界
ans = 0
for i in range(len(heights)):
while stack and heights[stack[- 1]] > heights[i]:
cur = stack.pop()
ans = max(ans, heights[cur] * (i - 1 - stack[-1])) # 出棧時進行相應計算
stack.append(i)
return ans
二叉搜尋樹
二叉搜尋樹能夠高效進行如下操作:
(1)插入一個數值
(2)查詢是否包含某個數值
(3)刪除某個數值
二叉搜尋樹所有的節點滿足左子樹上的所有節點都比自己小,右子樹上的所有節點都比自己大。
leetcode-98 驗證二叉搜尋樹
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
# 二叉樹的中序遍歷
stack = []
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
print(root.val)
root = root.right
字典樹
利用巢狀雜湊表來構建字典樹
0-1字典樹
leetcode-421 陣列中兩個數的最大異或值
並查集
一種管理元素分組情況的資料結構,可以高效的進行一下操作:
(1)查詢元素a和元素b是否屬於同一組
(2)合併元素a和元素b所在的組