Skip to content

Commit 466b180

Browse files
committed
Leetocde 算法提交
1 parent 6a9ab8f commit 466b180

17 files changed

+470
-1
lines changed

Leetcode121.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def maxProfit(self, prices):
3+
res = 0
4+
minValue = float("inf")
5+
for i in range(len(prices)):
6+
if prices[i] < minValue: #更新最小值
7+
minValue = prices[i]
8+
if prices[i] - minValue > res: #更新最大收益
9+
res = prices[i] - minValue
10+
return res

Leetcode126.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution:
2+
def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
3+
wordList.append(beginWord)
4+
### 构建具有邻接关系的桶
5+
buckets = defaultdict(list)
6+
for word in wordList:
7+
for i in range(len(beginWord)):
8+
match = word[:i] + '_' + word[i+1:]
9+
buckets[match].append(word)
10+
##### BFS遍历
11+
preWords = defaultdict(list) # 前溯词列表
12+
toSeen = deque([(beginWord, 1)]) # 待遍历词及深度
13+
beFound = {beginWord:1} # 已探测词列表
14+
while toSeen:
15+
curWord, level = toSeen.popleft()
16+
for i in range(len(beginWord)):
17+
match = curWord[:i] + '_' + curWord[i+1:]
18+
for word in buckets[match]:
19+
if word not in beFound:
20+
beFound[word] = level+1
21+
toSeen.append((word, level+1))
22+
if beFound[word] == level+1: # 当前深度等于该词首次遍历深度,则仍应加入前溯词列表
23+
preWords[word].append(curWord)
24+
if endWord in beFound and level+1 > beFound[endWord]: # 已搜索到目标词,且完成当前层遍历
25+
break
26+
#### 列表推导式输出结果
27+
if endWord in beFound:
28+
res = [[endWord]]
29+
while res[0][0] != beginWord:
30+
res = [[word] + r for r in res for word in preWords[r[0]]]
31+
return res
32+
else:
33+
return []

Leetcode129.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Definition for a binary tree node.
2+
# class TreeNode:
3+
# def __init__(self, x):
4+
# self.val = x
5+
# self.left = None
6+
# self.right = None
7+
8+
class Solution:
9+
def sumNumbers(self, root: TreeNode) -> int:
10+
res = []
11+
def dfs(node):
12+
if not node:
13+
return None
14+
if not node.left and not node.right:
15+
res.append(node.val)
16+
return
17+
dfs(node.left)
18+
dfs(node.right)
19+
dfs(root)
20+
return res

Leetcode13.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def romanToInt(self, s: str) -> int:
3+
roman_dic = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
4+
str_lenth=len(s)
5+
res=0
6+
for i in range(str_lenth):
7+
if i<str_lenth-1 and roman_dic[s[i]]<roman_dic[s[i+1]]:
8+
res-=roman_dic[s[i]]
9+
else:
10+
res+=roman_dic[s[i]]
11+
return res
12+

Leetcode130.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class Solution:
2+
def solve(self, board: List[List[str]]) -> None:
3+
"""
4+
Do not return anything, modify board in-place instead.
5+
"""
6+
if not board or not board[0]:
7+
return
8+
row = len(board)
9+
col = len(board[0])
10+
11+
def bfs(i, j):
12+
from collections import deque
13+
queue = deque()
14+
queue.appendleft((i, j))
15+
while queue:
16+
i, j = queue.pop()
17+
if 0 <= i < row and 0 <= j < col and board[i][j] == "O":
18+
board[i][j] = "B"
19+
for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
20+
queue.appendleft((i + x, j + y))
21+
22+
for j in range(col):
23+
# 第一行
24+
if board[0][j] == "O":
25+
bfs(0, j)
26+
# 最后一行
27+
if board[row - 1][j] == "O":
28+
bfs(row - 1, j)
29+
30+
for i in range(row):
31+
32+
if board[i][0] == "O":
33+
bfs(i, 0)
34+
if board[i][col - 1] == "O":
35+
bfs(i, col - 1)
36+
37+
for i in range(row):
38+
for j in range(col):
39+
if board[i][j] == "O":
40+
board[i][j] = "X"
41+
if board[i][j] == "B":
42+
board[i][j] = "O"

Leetcode139.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
3+
dp = [True, s[0] in wordDict]
4+
for i in range(1, len(s)):
5+
for j in range(i+1):
6+
if s[j: i+1] in wordDict and dp[j]:
7+
dp.append(True)
8+
break
9+
else:
10+
dp.append(False)
11+
return dp[-1]
12+

Leetcode143.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def reorderList(self, head: ListNode) -> None:
3+
if not head or not head.next:
4+
return head
5+
# 用快慢指针把链表一分为二,前半部分长度 >= 后半部分长度
6+
# first 为前半部分的头部,second 为后半部分的头部
7+
first = low = fast = head
8+
while fast.next and fast.next.next:
9+
fast, low = fast.next.next, low.next
10+
second, node, low.next, second.next = low.next, low.next.next, None, None
11+
# 后半部分逆序
12+
while node:
13+
node.next, second, node = second, node, node.next
14+
# 前后部分交替链接
15+
while second:
16+
first.next, second.next, first, second = second, first.next, first.next, second.next

Leetcode146.py

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
class ListNode:
2+
def __init__(self, key, val):
3+
self.key, self.val, self.prev, self.next = key, val, None, None
4+
5+
class MyOrderedDict:
6+
""" 哈希表 + 双向链表实现有序字典
7+
- 双向链表,记录键值插入顺序
8+
- 哈希表,记录键与节点映射关系,以O(1)复杂度查找、删除节点
9+
"""
10+
def __init__(self):
11+
self.head, self.tail = ListNode(0, 0), ListNode(0, 0)
12+
self.head.next, self.tail.prev = self.tail, self.head
13+
self.lookup = {} # 记录键与节点映射关系
14+
15+
def delete(self, node): # 删除节点
16+
self.lookup.pop(node.key)
17+
node.prev.next, node.next.prev = node.next, node.prev
18+
19+
def append(self, node): # 插入节点
20+
self.lookup[node.key] = node
21+
cur, pre = self.tail, self.tail.prev
22+
node.next, node.prev = cur, pre
23+
pre.next, cur.prev = node, node
24+
25+
def move_to_end(self, key):
26+
node = self.lookup[key]
27+
self.delete(node)
28+
self.append(node)
29+
30+
def pop(self, key):
31+
if len(self.lookup) == 0:
32+
raise Exception('Empty dict')
33+
node = self.lookup[key]
34+
self.delete(node)
35+
return node.val
36+
37+
def popitem(self, last=True):
38+
if len(self.lookup) == 0:
39+
raise Exception('Empty dict')
40+
41+
if last:
42+
node = self.tail.prev
43+
else:
44+
node = self.head.next
45+
self.delete(node)
46+
return node.val
47+
48+
def __len__(self):
49+
return len(self.lookup)
50+
51+
def __contains__(self, key) -> bool:
52+
return key in self.lookup
53+
54+
def __setitem__(self, key: int, value: int) -> None:
55+
""" 存在更新,不存在则插入 """
56+
if key in self.lookup:
57+
self.lookup[key].val = value
58+
else:
59+
self.append(ListNode(key, value))
60+
61+
def __getitem__(self, key: int) -> int:
62+
""" 存在返回键对应值,否则返回 -1 """
63+
if key in self.lookup:
64+
return self.lookup[key].val
65+
else:
66+
return -1
67+
68+
def get(self, key: int, default=None):
69+
if key in self.lookup:
70+
return self.lookup[key].val
71+
return default
72+
73+
def __iter__(self):
74+
cur = self.head.next
75+
while cur != self.tail:
76+
yield cur
77+
cur = cur.next
78+
79+
def __str__(self):
80+
res = []
81+
for node in self:
82+
res.append((node.key, node.val))
83+
return "MyOrderedDict({})".format(str(res))
84+
85+
class LRUCache:
86+
""" 有序字典实现LruCache """
87+
def __init__(self, capacity: int):
88+
self.lru_cache = MyOrderedDict()
89+
self.maxsize = capacity
90+
91+
def get(self, key: int) -> int:
92+
""" 存在key 移动到末尾并返回对应值, 否则返回-1"""
93+
if key in self.lru_cache:
94+
self.lru_cache.move_to_end(key)
95+
return self.lru_cache.get(key, -1)
96+
97+
def put(self, key: int, value: int) -> None:
98+
if key in self.lru_cache:
99+
self.lru_cache.pop(key)
100+
if len(self.lru_cache) == self.maxsize: # 缓存满
101+
self.lru_cache.popitem(last=False)
102+
self.lru_cache[key] = value

Leetcode148.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Definition for singly-linked list.
2+
# class ListNode:
3+
# def __init__(self, val=0, next=None):
4+
# self.val = val
5+
# self.next = next
6+
class Solution:
7+
def sortList(self, head: ListNode) -> ListNode:
8+
from queue import PriorityQueue
9+
ptr = head
10+
p_queue = PriorityQueue()
11+
while ptr != None:
12+
p_queue.put(ptr.val)
13+
ptr = ptr.next
14+
15+
ptr = head
16+
while not p_queue.empty():
17+
ptr.val = p_queue.get()
18+
ptr = ptr.next
19+
return head

Leetcode162.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution:
2+
def findPeakElement(self, nums: List[int]) -> int:
3+
if len(nums) == 1: return 0
4+
left, right = 0, len(nums)-1
5+
while left <= right:
6+
mid = (left+right) // 2
7+
if mid == 0:
8+
if nums[mid] > nums[mid+1]:
9+
return mid
10+
else:
11+
left = mid+1
12+
elif mid == len(nums)-1:
13+
if nums[mid] > nums[mid-1]:
14+
return mid
15+
else:
16+
right = mid-1
17+
elif nums[mid-1] < nums[mid] and nums[mid] > nums[mid+1]:
18+
return mid
19+
elif nums[mid] > nums[mid-1]:
20+
left = mid+1
21+
elif nums[mid] < nums[mid-1]:
22+
right = mid-1

Leetcode33.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution:
2+
def search(self, nums: List[int], target: int) -> int:
3+
"""用二分法,先判断左右两边哪一边是有序的,再判断是否在有序的列表之内"""
4+
if len(nums) <= 0:
5+
return -1
6+
7+
left = 0
8+
right = len(nums) - 1
9+
while left < right:
10+
mid = (right - left) // 2 + left
11+
if nums[mid] == target:
12+
return mid
13+
14+
# 如果中间的值大于最左边的值,说明左边有序
15+
if nums[mid] > nums[left]:
16+
if nums[left] <= target <= nums[mid]:
17+
right = mid
18+
else:
19+
# 这里 +1,因为上面是 <= 符号
20+
left = mid + 1
21+
# 否则右边有序
22+
else:
23+
# 注意:这里必须是 mid+1,因为根据我们的比较方式,mid属于左边的序列
24+
if nums[mid+1] <= target <= nums[right]:
25+
left = mid + 1
26+
else:
27+
right = mid
28+
29+
return left if nums[left] == target else -1

Leetcode387.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def countAndSay(self, n: int) -> str:
3+
pre = ''
4+
cur = '1'
5+
6+
# 从第 2 项开始
7+
for _ in range(1, n):
8+
# 这里注意要将 cur 赋值给 pre
9+
# 因为当前项,就是下一项的前一项。有点绕,尝试理解下
10+
pre = cur
11+
# 这里 cur 初始化为空,重新拼接
12+
cur = ''
13+
# 定义双指针 start,end
14+
start = 0
15+
end = 0
16+
# 开始遍历前一项,开始描述
17+
while end < len(pre):
18+
# 统计重复元素的次数,出现不同元素时,停止
19+
# 记录出现的次数,
20+
while end < len(pre) and pre[start] == pre[end]:
21+
end += 1
22+
# 元素出现次数与元素进行拼接
23+
cur += str(end-start) + pre[start]
24+
# 这里更新 start,开始记录下一个元素
25+
start = end
26+
27+
return cur

Leetcode44.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def permute(self, nums: List[int]) -> List[List[int]]:
6+
def dfs(nums, size, depth, path, used, res):
7+
if depth == size:
8+
res.append(path)
9+
return
10+
11+
for i in range(size):
12+
if not used[i]:
13+
used[i] = True
14+
path.append(nums[i])
15+
16+
dfs(nums, size, depth + 1, path, used, res)
17+
18+
used[i] = False
19+
path.pop()
20+
21+
size = len(nums)
22+
if len(nums) == 0:
23+
return []
24+
25+
used = [False for _ in range(size)]
26+
res = []
27+
dfs(nums, size, 0, [], used, res)
28+
return res
29+
30+
31+
if __name__ == '__main__':
32+
nums = [1, 2, 3]
33+
solution = Solution()
34+
res = solution.permute(nums)
35+
print(res)

0 commit comments

Comments
 (0)