Skip to content

Commit 95ed3cc

Browse files
author
aaron.liu
committed
update
1 parent 8090be8 commit 95ed3cc

13 files changed

+364
-59
lines changed

Diff for: Array/LC247StrobogrammaticNumberII.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution:
2+
def findStrobogrammatic(self, n: int) -> List[str]:
3+
map = {
4+
"0": "0",
5+
"1": "1",
6+
"6": "9",
7+
"8": "8",
8+
"9": "6",
9+
}
10+
11+
ret = []
12+
13+
if n % 2 == 1:
14+
ret = ["0", "1", "8"]
15+
n -= 1
16+
else:
17+
ret = [""]
18+
19+
while n:
20+
size = len(ret)
21+
while size:
22+
size -= 1
23+
cur = ret.pop(0)
24+
for key in map:
25+
if n == 2 and key == "0":
26+
continue
27+
ret.append(key + cur + map[key])
28+
n -= 2
29+
return ret

Diff for: Array/LC468 Validate IP Address.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Aaron solution
2+
# Time O(N)
3+
# Space O(N)
4+
def validIPAddress(self, queryIP: str) -> str:
5+
6+
def is_ip_v4(s):
7+
address = s.split(".")
8+
if len(address) != 4: return False
9+
for item in address:
10+
if not item.isdigit() or str(int(item)) != item or int(item) > 255: # str(int(item)) != item -> 判断是否有leading zeros. 如果有 int()会把前导0消除 在str()回去 就跟原始的item不同
11+
return False
12+
return True
13+
14+
def is_ip_v6(s):
15+
address = s.split(":")
16+
if len(address) != 8: return False
17+
for item in address:
18+
if len(item) < 1 or len(item) > 4: return False
19+
for ch in item.lower(): # 先转换成小写
20+
if 'a' <= ch <= 'f' or '0' <= ch <= '9':
21+
continue
22+
else:
23+
return False
24+
return True
25+
26+
if is_ip_v4(queryIP): return "IPv4"
27+
return "IPv6" if is_ip_v6(queryIP) else "Neither"

Diff for: Array/LC825FriendsOfAppropriateAges.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from typing import List
2+
3+
class Solution:
4+
def numFriendRequests(self, ages: List[int]) -> int:
5+
size = len(ages) # 有多少人
6+
7+
age_num = [0] * 121 # age_num[i]: 第i岁有多少人
8+
for age in ages:
9+
age_num[age] += 1
10+
11+
ret = size * size # 可能的所有请求个数 后面会剔除非法的请求
12+
for i in range(1, 121): # 枚举所有可能的年龄(代表某个人)
13+
for j in range(1, 121): # 枚举所有可能的年龄(代表某个人)
14+
if (j <= 0.5 * i + 7) or (j > i):
15+
ret -= age_num[i] * age_num[j]
16+
elif j == i: # 剔除自己向自己发请求(自环)
17+
ret -= age_num[j]
18+
return ret

Diff for: Array/Meta reorder string.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'''
2+
输入一个字符串s 要求根据s里的字符出现的frequency从高到低重新排序。e.g. "mammamia" -> "mmmmaaai".
3+
如果字符出现次数相同,按字母表顺序排列相同频率的字符
4+
'''
5+
6+
from collections import Counter
7+
8+
def frequency_sort(s: str) -> str:
9+
# Step 1: 统计每个字符的频率
10+
freq = Counter(s)
11+
12+
# Step 2: 按照频率和字母顺序排序
13+
# 使用 (-freq[char], char) 作为排序键,先按频率降序,再按字母升序
14+
sorted_chars = sorted(freq.keys(), key=lambda ch: (-freq[ch], ch))
15+
16+
# Step 3: 根据排序结果重构字符串
17+
result = ''.join(char * freq[char] for char in sorted_chars)
18+
19+
# step 3 也能这么写
20+
#result = ''
21+
#for char in sorted_chars:
22+
# result += char * freq[char]
23+
24+
return result
25+
26+
# 测试
27+
print(frequency_sort("mammamia")) # 输出: "mmmmaaai"
28+
print(frequency_sort("tree")) # 输出: "eert"
29+
print(frequency_sort("cccaaa")) # 输出: "aaaccc"
30+
print(frequency_sort("Aabb")) # 输出: "bbAa"

Diff for: Array/Meta second largest num.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Given a list of numbers (0-9) arrange the numbers in the second greatest number
2+
3+
from typing import List
4+
from collections import Counter
5+
6+
def find_sencond_largest(nums: List[int]) -> int:
7+
# 将数字转换为字符串并计数
8+
counter = Counter(num for num in nums)
9+
max_digit, min_digit = -1, 10
10+
11+
for key in counter.keys():
12+
max_digit = max(max_digit, key)
13+
min_digit = min(min_digit, key)
14+
15+
if max_digit == 0:
16+
return 0
17+
18+
# 构建最大数
19+
max_num = []
20+
for num in range(max_digit, min_digit - 1, -1):
21+
if num in counter:
22+
cur = [num] * counter[num]
23+
max_num.extend(cur)
24+
25+
# 从右向左查找第一个可以减小的数字
26+
# 877777
27+
# 11000
28+
pivot = -1
29+
for i in range(len(max_num) - 1, 0, -1):
30+
if max_num[i - 1] > max_num[i]:
31+
pivot = i - 1
32+
33+
if pivot != -1 and not (max_num[i] == 0 and i - 1 == 0):
34+
max_num[i - 1], max_num[i] = max_num[i], max_num[i - 1]
35+
print("final list", [str(s) for s in max_num])
36+
return int(''.join([str(s) for s in max_num]))
37+
return int(''.join(max_num))
38+
39+
print(find_sencond_largest([5,3,2,5,5,7,9,8]))
40+
print(find_sencond_largest([9,8,7,6,5,4,3,2,1,0]))
41+
print(find_sencond_largest([1,2,3,4,5]))
42+
print(find_sencond_largest([1,1,0,0,0]))

Diff for: BinarySearch/LC26RemoveDuplicatesFromSortedArray.py

Whitespace-only changes.

Diff for: DFS/Meta_cleaning_robot.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'''
2+
variation of LC 489
3+
find cheese and instead of manual rotation, the robot can move in any direction
4+
assume cheese
5+
'''
6+
from typing import List
7+
8+
class Robot:
9+
def check_cheese(self) -> bool:
10+
pass
11+
12+
def move(self) -> bool:
13+
pass
14+
15+
16+
def find_cheese(robot: Robot):
17+
directions = [(-1, 0), (1, 0), (0, 1), (0, -1)]
18+
visited = set()
19+
visited.add((0, 0))
20+
dfs(robot, directions, 0, 0, visited)
21+
22+
def dfs(robot: Robot, directions: List[tuple[int, int]], x: int, y: int, visited: set) -> List[int]:
23+
if robot.check_cheese():
24+
return [x, y]
25+
26+
for i in range(4):
27+
nx = x + directions[i][0]
28+
ny = y + directions[i][1]
29+
if (nx, ny) not in visited and robot.move():
30+
visited.add(nx, ny)
31+
dfs(robot, directions, nx, ny, visited)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'''
2+
Given an linked list nums and an integer k, return the k most frequent elements. You may return the answer in any order.
3+
4+
Example 1:
5+
6+
Input: nums = [1,1,1,2,2,3], k = 2
7+
Output: [1,2]
8+
Example 2:
9+
10+
Input: nums = [1], k = 1
11+
Output: [1]
12+
13+
14+
Constraints:
15+
16+
1 <= nums.length <= 105
17+
-104 <= nums[i] <= 104
18+
k is in the range [1, the number of unique elements in the array].
19+
It is guaranteed that the answer is unique.
20+
'''
21+
from collections import defaultdict
22+
import heapq
23+
24+
class ListNode:
25+
def __init__(self, x):
26+
self.val = x
27+
self.next = None
28+
29+
30+
def topKFrequent(head: ListNode, k: int) -> list:
31+
# Step 1: Count the frequency of each element in the linked list
32+
frequency = defaultdict(int)
33+
current = head
34+
35+
while current:
36+
frequency[current.val] += 1
37+
current = current.next
38+
39+
# Step 2: Use a min-heap to keep track of the top k elements
40+
min_heap = []
41+
42+
for num, freq in frequency.items():
43+
heapq.heappush(min_heap, (freq, num))
44+
if len(min_heap) > k:
45+
heapq.heappop(min_heap)
46+
47+
# Step 3: Extract the elements from the heap
48+
result = []
49+
while min_heap:
50+
result.append(heapq.heappop(min_heap)[1])
51+
52+
return result
53+
54+
# Helper function to create linked list from list of values
55+
def create_linked_list(values):
56+
if not values:
57+
return None
58+
head = ListNode(values[0])
59+
current = head
60+
for value in values[1:]:
61+
current.next = ListNode(value)
62+
current = current.next
63+
return head
64+
65+
# Test case 1
66+
nums = create_linked_list([1, 1, 1, 2, 2, 3])
67+
k = 2
68+
print(topKFrequent(nums, k)) # Output: [1, 2]
69+
70+
# Test case 2
71+
nums = create_linked_list([1])
72+
k = 1
73+
print(topKFrequent(nums, k)) # Output: [1]

Diff for: Memo/LC2060CheckIfAnOriginalStringExistsGivenTwoEncodedStrings.py

-10
This file was deleted.

Diff for: Tree/LC958CheckCompletenessOfABinaryTree.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from typing import Optional
2+
import collections
3+
4+
# Definition for a binary tree node.
5+
class TreeNode:
6+
def __init__(self, val=0, left=None, right=None):
7+
self.val = val
8+
self.left = left
9+
self.right = right
10+
11+
class Solution:
12+
def isCompleteTree(self, root: Optional[TreeNode]) -> bool:
13+
seen_null = False
14+
queue = collections.deque([root])
15+
while queue:
16+
if seen_null:
17+
return not any(queue)
18+
19+
for _ in range(len(queue)):
20+
node = queue.popleft()
21+
if not node:
22+
seen_null = True
23+
else:
24+
if seen_null:
25+
return False
26+
queue.append(node.left)
27+
queue.append(node.right)
28+
return True

Diff for: Tree/doordash_num_of_menu_updates.py

+27-13
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,39 @@
44

55
from typing import List
66

7-
87
class Node:
98
def __init__(self, key:str=None, val:int=None, children:List['Node']=[]):
109
self.key = key
1110
self.val = val
1211
self.children = children
1312

1413
def compare_old_and_updated_menus(root_o: Node, root_u: Node) -> int:
15-
return dfs_compare(root_o, root_u)
14+
diff = []
15+
ret = dfs_compare(root_o, root_u, diff)
16+
print([item.key for item in diff])
17+
return ret
1618

17-
def count_nodes(root: Node) -> int:
19+
def count_nodes(root: Node, diff: List=[]) -> int:
1820
if not root:
1921
return 0
22+
diff.append(root)
2023
num = 1
2124
for child in root.children:
2225
num += count_nodes(child)
2326
return num
2427

25-
def dfs_compare(root_o: Node, root_u: Node) -> int:
28+
def dfs_compare(root_o: Node, root_u: Node, diff: List) -> int:
2629
if not root_o and not root_u:
2730
return 0
2831
if not root_o:
29-
return count_nodes(root_u)
32+
return count_nodes(root_u, diff)
3033
if not root_u:
31-
return count_nodes(root_o)
34+
return count_nodes(root_o, diff)
3235
if root_o.key != root_u.key:
33-
return count_nodes(root_u) + count_nodes(root_o)
34-
36+
return count_nodes(root_u, diff) + count_nodes(root_o, diff)
3537
diff_cnt = 0
3638
if root_o.val != root_u.val:
39+
diff.append(root_o)
3740
diff_cnt += 1
3841

3942
origin_map = {}
@@ -44,24 +47,35 @@ def dfs_compare(root_o: Node, root_u: Node) -> int:
4447
for child in root_u.children:
4548
if child.key in origin_map:
4649
visited.add(child.key)
47-
diff_cnt += dfs_compare(origin_map[child.key], child)
50+
diff_cnt += dfs_compare(origin_map[child.key], child, diff)
4851
else:
49-
diff_cnt += count_nodes(child)
52+
diff_cnt += count_nodes(child, diff)
5053

5154
for child in root_o.children:
5255
if child.key not in visited:
53-
diff_cnt += count_nodes(child)
56+
diff_cnt += count_nodes(child, diff)
5457
return diff_cnt
5558

56-
5759
# case 1
60+
'''
5861
d_o, e_o, f_o = Node("d", 4), Node("e", 5), Node("f", 6)
5962
b_o, c_o = Node("b", 2, [d_o, e_o]), Node("c", 3, [f_o])
6063
a_o = Node("a", 1, [b_o, c_o]) # a_o is the root_o
6164
6265
f_u = Node("f", 66)
6366
c_u = Node("c", 3, [f_u])
6467
a_u = Node("a", 1, [c_u]) # a_u is the root_u
68+
'''
69+
# case 2
70+
old_tree = Node("root", 1, [])
71+
child1_old = Node("child1", 2, [])
72+
child2_old = Node("child2", 3, [])
73+
old_tree.children = [child1_old, child2_old]
74+
6575

76+
new_tree = Node("root", 1, [])
77+
child1_new = Node("child1", 5, []) # Value changed
78+
child3_new = Node("child3", 4, []) # New node
79+
new_tree.children = [child1_new, child3_new]
6680

67-
print(compare_old_and_updated_menus(a_o, a_u))
81+
print(compare_old_and_updated_menus(old_tree, new_tree))

0 commit comments

Comments
 (0)