一、数据结构
2、链表题
2.1 力扣203
2.2 力扣206 反转链表
方法一、迭代1
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
dummy = ListNode()
dummy.next = head
while (head != None and head.next != None):
dnext = dummy.next
hnext = head.next
dummy.next, head.next, hnext.next = head.next, hnext.next, dummy.next
return dummy.next
方法二、迭代2
def reverseList(self, head: ListNode) -> ListNode:
prev, curr = None, head
while curr is not None:
next = curr.next
curr.next = prev
prev = curr
curr = next
return prev
方法二、递归
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
p = self.reverseList(head.next)
head.next.next = head
head.next = None
return p
3、队列
先进先出
创建队列
# 创建的是双端队列
from collections import *
queue = deque()
# 添加元素
queue.append(1)
queue.append(2)
print(queue)
# 获取即将出队的元素
temp1 = queue[0]
print(temp1)
# 删除即将出队的元素返回删除的值
temp2 = queue.popleft()
print(temp2)
# 判断队列是否为空
len(queue) == 0
# 遍历队列
while len(queue) != 0:
temp = queue.popleft()
print(temp)
3.1 力扣 933 最近的请求次数
class RecentCounter:
def __init__(self):
self.Q = deque()
def ping(self, t: int) -> int:
self.Q.append(t)
while (len(self.Q) > 0 and t - self.Q[0] > 3000):
self.Q.popleft()
return len(self.Q)
4、栈
# 创建栈
stack = []
# 添加元素
stack.append(1)
stack.append(2)
# 获取栈顶元素
stack[-1]
# 删除栈顶元素
stack.pop()
# 栈的大小 O(1)
len(stack)
# 栈是否为空 O(1)
len(stack) == 0
# 遍历栈 O(N)
while len(stack) > 0:
temp = stack.pop()
print(temp)
4.1 力扣20 有效地括号
class Solution:
def isValid(self, s: str) -> bool:
self.s = s
stack = []
if len(self.s) == 0:
return True
for k in self.s:
if k == '(' or k == '[' or k == '{':
stack.append(k)
else:
if len(stack) == 0:
return False
elif k == ')':
if stack[-1] == '(':
stack.pop()
else:
return False
elif k == ']':
if stack[-1] == '[':
stack.pop()
else:
return False
elif k == '}':
if stack[-1] == '{':
stack.pop()
else:
return False
if stack:
return False
else:
return True
4.2 力扣 496 下一个更大元素!
自己写出来的!!!
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
ans = []
for i in nums1:
l = nums2.index(i)
for k in nums2[l:]:
if k > i :
ans.append(k)
break
else:
if k == nums2[-1]:
ans.append(-1)
return ans
用栈的思想解题:
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
ans = []
temp = []
for l in nums1:
max1 = -1
isfound = True
while len(nums2) != 0 and isfound:
top = nums2.pop()
temp.append(top)
if top > l:
max1 = top
else:
if top == l:
isfound = False
ans.append(max1)
while len(temp):
nums2.append(temp.pop())
return ans
5、哈希表
key:value
# 创建哈希表
hashtable = ['']*4
mappling = {}
# 添加元素
hashtable[1] = 'hanmeimei'
hashtable[2] = 'lihua'
mappling[1] = 'hanmeimei'
mappling[2] = 'lihua'
# 修改元素
hashtable[1] = 'bishi'
mappling[1] = 'bishi'
# 删除元素
hashtable[1] = ''
mappling.pop(1)
del mappling[1]
# 获取元素
hashtable[3]
mappling[3]
# 检查key是否存在
数组创建的只能遍历一遍
3 in mappling # 返回True False
# 哈希表的长度
len(mappling)
# 哈希表是否还有元素
len(mappling) == 0
5.1 217. 存在重复元素
太简单
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
len1 = len(nums)
len2 = len(set(nums))
if len1 == len2:
return False
else:
return True
5.2 389. 找不同
方法一
class Solution:
def findTheDifference(self, s: str, t: str) -> str:
list1 = []
for i in t:
list1.append(i)
for l in s:
list1.remove(l)
return list1[0]
方法二
class Solution:
def findTheDifference(self, s: str, t: str) -> str:
list1 = [0]*26
if len(s) == 0:
return t
for i in s:
temp = ord(i) - 97
list1[temp] -= 1
for l in t:
temp = ord(l) - 97
list1[temp] += 1
return chr(list1.index(1)+97)
6、集合
# 创建集合
s =set()
# 添加元素 O(1)
s.add(1)
s.add(2)
# 搜索元素 O(1)
2 in s
# 删除元素 O(1)
s.remove(2)
# 长度
len(s)
6.1 705. 设计哈希集合
class MyHashSet:
def __init__(self):
self.myHashSet = [False, ] * 1000001
def add(self, key: int) -> None:
self.myHashSet[key] = True
def remove(self, key: int) -> None:
self.myHashSet[key] = False
def contains(self, key: int) -> bool:
return self.myHashSet[key]
7、树 tree
前序:根 左 右
中序:左 根 右
后序:左 右 根
用Python创建最小堆
没有直接办法创建最大堆,方法就是把所有元素转换为负数
import heapq
class Test:
def test(self):
# Create minheap
minheap = []
heapq.heapify(minheap)
# Add element
heapq.heappush(minheap, 10)
heapq.heappush(minheap, 8)
heapq.heappush(minheap, 9)
heapq.heappush(minheap, 2)
heapq.heappush(minheap, 1)
heapq.heappush(minheap, 11)
# [1, 2, 9, 10, 8, 11]
print(minheap)
# peek
# 1
print(minheap[0])
# Delete
heapq.heappop(minheap)
# size
len(minheap)
# Iteration
while len(minheap) != 0:
print(heapq.heappop(minheap))
7.1 前中后序遍历方法
root = [1, 'null', 2, 3]
# 前序遍历 根 左 右
def preordertraversal(root):
stack, res = [], []
while root or stack:
while root:
res.append(root.val)
stack.append(root)
root = root.left
cur = stack.pop()
root = cur.right
return res
# 中序遍历 左 根 右
def inordertraversal(root):
stack, res = [], []
while root or stack:
while root:
stack.append(root)
root = root.left
root = stack.pop()
res.append(root.val)
root = root.right
return res
# 后续遍历 左 右 根
def postordertraversal(root):
stack, res = [], []
while root or stack:
while root:
res.append(root.val)
stack.append(root)
root = root.right
cur = stack.pop()
root = cur.left
res.reverse() # 把 根 右 左 反转为 左 右 根
return res
7.2 692. 前K个高频单词
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
dic = collections.Counter(words)
heap, ans = [], []
for i in dic:
heapq.heappush(heap, (-dic[i], i))
for _ in range(k):
ans.append(heapq.heappop(heap)[1])
return ans
8、图
- 无向图
- 有向图
- 权重图
二、算法
1、双指针 Two Pointers
- 普通双指针:两个指针往同一方向移动
- 对撞双指针:两个指针面对面移动
- 快慢双指针:慢指针 + 快指针
1.1 141. 环形链表
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
index1 = head
index2 = head
if head == None:
return False
while index2 != None and index2.next != None:
index1 = index1.next
index2 = index2.next.next
if index1 == index2:
return True
break
return False
1.2 881. 救生艇
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
if people == None:
return 0
people.sort()
res = 0
i = 0
j = len(people) - 1
while (i <= j):
if (people[i] + people[j] <= limit):
i += 1
j -= 1
res += 1
return res
2、 二分法查找
2.1 704. 二分查找
class Solution:
def search(self, nums: List[int], target: int) -> int:
if target not in nums:
return -1
else:
r = 0
l = len(nums) - 1
while r <= l:
mid = (l - r) // 2 + r
if nums[mid] < target:
r = mid + 1
elif nums[mid] > target:
l = mid - 1
else:
return mid
2.2 35. 搜索插入位置
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums) - 1
while l <= r:
mid = (r - l) // 2 + l
if nums[mid] < target:
l = mid + 1
elif nums[mid] > target:
r = mid - 1
else:
return mid
return l
2.3 162. 寻找峰值
方法一
方法二class Solution:
def findPeakElement(self, nums: List[int]) -> int:
if len(nums) < 2:
return 0
elif len(nums) == 2:
if nums[0] > nums[1]:
return 0
else:
return 1
l = 0
m = l + 1
r = l + 2
while (r < len(nums)):
if nums[l] < nums[m] > nums[r]:
return m
elif nums[l] > nums[m]:
return l
elif nums[r] > nums[m] and len(nums) == r + 1:
return r
else:
l += 1
m = l + 1
r = l + 2
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
l = 0
r = len(nums) - 1
while l < r:
mid = (r - l) // 2 + l
if nums[mid] > nums[mid+1]:
r = mid
else:
l = mid + 1
return l
2.4 74. 搜索二维矩阵
遍历法class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
k = 0
li = []
for i in matrix:
for l in i:
li.append(l)
l = 0
r = l + 1
while r < len(li):
if li[r] >= li[l]:
l += 1
r = l + 1
else:
return False
if l == len(li)-1 and target in li:
return True
else:
return False
```python class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
if len(matrix) == 0 or matrix == None:
return False
row = len(matrix)
col = len(matrix[0])
l = 0
r = row * col - 1
while l <= r:
m = (r - l) // 2 + l
element = matrix[m // col][m % col]
if element == target:
return True
elif element > target:
r = m - 1
else:
l = m + 1
return False
<a name="L3v4Z"></a>
## 3、滑动窗口 Sliding Window
目的:减少while循环
<a name="HZSQs"></a>
### 3.1 [209. 长度最小的子数组](https://leetcode-cn.com/problems/minimum-size-subarray-sum/)
```python
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
if len(nums) == 0:
return 0
r = 0
l = 0
res = len(nums) + 1
total = 0
while l < len(nums):
total += nums[l]
l += 1
while total >= target:
res = min(res, l - r)
total -= nums[r]
r += 1
if res == len(nums) + 1:
return 0
else:
return res
3.2 1456. 定长子串中元音的最大数目
class Solution:
def maxVowels(self, s: str, k: int) -> int:
if len(s) == 0 or len(s) < k:
return 0
res = count = 0
yuan = ['a', 'e', 'i', 'o', 'u']
for i in range(0, k):
if s[i] in yuan:
count += 1
res = max(res, count)
for i in range(k, len(s)):
if s[i - k] in yuan:
count -= 1
if s[i] in yuan:
count += 1
res = max(res, count)
return res
4、递归
递归四要素
- 接受的参数
- 返回值
- 终止的条件
- 递归的拆解:如何递归下一层
def reasion():
if n == 0:
return 0
m = reasion(n-1)
return m
4.1 509. 斐波那契数
class Solution:
def fib(self, n: int) -> int:
if n < 2:
return 0 if n == 0 else 1
m = self.fib(n - 1) + self.fib(n - 2)
return m
4.2 206.反转链表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
p = self.reverseList(head.next)
head.next.next = head
head.next = None
return p
5、分治法