3. 无重复字符的最长子串
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
res = 0
visited = list()
# 先左移后右移窗口
for i in range(len(s)):
# 左移窗口
while s[i] in visited: visited.pop(0)
# 右移窗口
visited.append(s[i])
res = max(res, len(visited))
return res
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:
pre, cur = None, head
while cur:
# 存储当前链表的下一个节点为临时变量
tmp = cur.next
# 当前链表的下一个指向前一个链表
cur.next = pre
# pre, cur整体往后移动一个位置
pre, cur = cur, tmp
return pre
146. LRU 缓存
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity: int):
# OrderedDict的key会按照插入的顺序排列,不是key本身排序
self.capacity = capacity
self.dict = OrderedDict()
def get(self, key: int) -> int:
# 说明在字典中,重新移动字典的尾部
if key in self.dict:
self.dict.move_to_end(key)
return self.dict.get(key, -1)
def put(self, key: int, value: int) -> None:
# 如果存在,删掉,重新赋值
if key in self.dict:
del self.dict[key]
# 在字典尾部添加
self.dict[key] = value
if len(self.dict) > self.capacity:
# 弹出字典的头部(因为存储空间不够了)
# OrderedDict.popitem()有一个可选参数last(默认为True),当last为True时它从OrderedDict中删除最后一个键值对并返回该键值对,当last为False时它从OrderedDict中删除第一个键值对并返回该键值对
self.dict.popitem(last=False)
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
215. 数组中的第K个最大元素
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def quick_sort(a, l, r, k):
if l >= r: return a[l]
i = l - 1; j = r + 1
x = a[l + r >> 1]
while i < j:
i += 1
while a[i] < x: i += 1
j -= 1
while a[j] > x: j -= 1
if i < j: a[i], a[j] = a[j], a[i]
s1 = j - l + 1
if k <= s1: return quick_sort(a, l, j, k)
else: return quick_sort(a, j + 1, r, k - s1)
return quick_sort(nums, 0, len(nums) - 1, len(nums) - k + 1)
# 第k个数是正序,本题是逆序
25. K 个一组翻转链表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
# 判断是否有k个节点
def cal_len(head):
p = head
cnt = 0
while p:
cnt += 1
p = p.next
if cnt >= k: return True
return False
# 翻转k个节点
def reverseK(head, k):
pre, cur = None, head
while k:
tmp = cur.next
cur.next = pre
pre, cur = cur, tmp
k -= 1
return pre, cur
# 递归
def dfs(head, k):
if not cal_len(head): return head
pre, cur = reverseK(head, k)
head.next = dfs(cur, k)
return pre
return dfs(head, k)
15. 三数之和
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
n = len(nums)
nums.sort()
for i in range(n):
l = i + 1; r = n - 1
# 减枝,可省略
if nums[i] > 0: break
# nums[i] 去重,一定使用 i - 1
if i > 0 and nums[i] == nums[i-1]: continue
while l < r:
sums = nums[i] + nums[l] + nums[r]
if sums < 0: l += 1
elif sums > 0: r -= 1
else:
res.append([nums[i], nums[l], nums[r]])
# nums[l] nums[r] 去重
while l < r and nums[l] == nums[l+1]: l += 1
while l < r and nums[r] == nums[r-1]: r -= 1
# 最后再多走一步
l += 1; r -= 1
return res
53. 最大子数组和
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
dp = [0] * n
dp[0] = nums[0]
# dp 以下标 i 结尾的最大和的连续子数组
for i in range(1, n):
if dp[i-1] > 0:
dp[i] = dp[i-1] + nums[i]
else:
dp[i] = nums[i]
return max(dp)
912. 排序数组
# python
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def quick_sort(a, l, r):
if l >= r: return a
i = l - 1; j = r + 1; x = a[l + r >> 1]
while i < j:
i += 1
while a[i] < x: i += 1
j -= 1
while a[j] > x: j -= 1
if i < j: a[i], a[j] = a[j], a[i]
quick_sort(a, l, j); quick_sort(a, j+1, r)
return a
return quick_sort(nums, 0, len(nums)-1)
# python 模拟 c++ do while 循环
# while True: do() if fail_condition: break
# do(); while condtion: do()
21. 合并两个有序链表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
head = cur = ListNode(0)
while list1 and list2:
if list1.val <= list2.val:
cur.next = list1
list1 = list1.next
else:
cur.next = list2
list2 = list2.next
cur = cur.next
# 合并后 list1 和 list2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
cur.next = list1 if list1 else list2
return head.next
1. 两数之和
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# 遍历列表同时查字典
map = dict()
for i, n in enumerate(nums):
m = target - n
if m in map:
return [map[m], i]
else:
map[n] = i # 这句不能放在if语句之前,解决list中有重复值或target-num=num的情况
102. 二叉树的层序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res = []
q = [root]
while q:
tmp = []
for i in range(len(q)):
node = q.pop(0)
tmp.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
res.append(tmp)
return res
5. 最长回文子串
class Solution:
def palindrome(self, s: str, left: int, right: int) -> str:
while(left>=0 and right<len(s) and s[left]==s[right]):
left-=1
right+=1
return s[left+1:right]
def longestPalindrome(self, s: str) -> str:
res=""
for i in range(len(s)):
#奇数回文子串
s1 = self.palindrome(s,i,i)
#偶数回文子串
s2 = self.palindrome(s,i,i+1)
res = res if len(res)>len(s1) else s1
res = res if len(res)>len(s2) else s2
return res
33. 搜索旋转排序数组
class Solution:
def search(self, nums: List[int], target: int) -> int:
if not nums: return -1
l = 0; r = len(nums) - 1
# 无重复数,在有序区间查找
while l <= r:
m = l + r >> 1
if nums[m] == target: return m # 因为存在找不到的情况,故在此return
# 可以用nums[l]和nums[m]判断有序,也可以用nums[m]和nums[r]判断有序
elif nums[l] <= nums[m]: # 左半部分是有序
# target落在左半部分有序区域内,去掉m
if nums[l] <= target < nums[m]:
r = m - 1
else:
l = m + 1
else: # 右半部分是有序
# target落在右半部分有序区域内,去掉m
if nums[m] < target <= nums[r]:
l = m + 1
else:
r = m - 1
return -1
# 2.1
# 时间复杂度:O(logn)
# 空间复杂度:O(1)
121. 买卖股票的最佳时机
class Solution:
def maxProfit(self, prices: List[int]) -> int:
minprice = float('inf')
maxprofit = 0
# 一次遍历
for price in prices:
minprice = min(minprice, price)
maxprofit = max(maxprofit, price-minprice)
return maxprofit
20. 有效的括号
class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2 == 1: return False
dict = {'(':')','[':']','{':'}'}
stack = list()
# stack中存左括号。 如果是左括号, 加入栈中; 如果是右括号, 判断栈顶元素的键的值是否等于当前元素; 栈 stack 为空: 此时 stack.pop() 操作会报错
for c in s:
if c in dict: stack.append(c)
elif not stack or dict[stack.pop()] != c: return False
return not stack
141. 环形链表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast: return True
return False
88. 合并两个有序数组
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
res = []
p1 = p2 = 0
while p1 < m or p2 < n:
if p1 == m:
res.append(nums2[p2])
p2 += 1
elif p2 == n:
res.append(nums1[p1])
p1 += 1
elif nums1[p1] <= nums2[p2]:
res.append(nums1[p1])
p1 += 1
else:
res.append(nums2[p2])
p2 += 1
nums1[:] = res
103. 二叉树的锯齿形层序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res = []
q = [root]
cnt = 0
while q:
tmp = []
for i in range(len(q)):
node = q.pop(0)
tmp.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
if cnt%2 == 0: res.append(tmp)
else: res.append(tmp[::-1])
cnt += 1
return res
200. 岛屿数量
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def dfs(grid, i, j):
if not (0 <= i < len(grid) and 0 <= j < len(grid[0])): return
if grid[i][j] != '1': return
grid[i][j] = '2'; # 将格子标记为「已遍历过」
dfs(grid, i - 1, j)
dfs(grid, i + 1, j)
dfs(grid, i, j - 1)
dfs(grid, i, j + 1)
res = 0
m, n = len(grid), len(grid[0])
for i in range(m):
for j in range(n):
if grid[i][j] == '1':
dfs(grid, i, j)
res += 1
return res
236. 二叉树的最近公共祖先
# Definitio