Skip to content

Commit d0a6cb1

Browse files
update
1 parent d97f8aa commit d0a6cb1

4 files changed

+159
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import List
2+
'''
3+
解法1: min heap.注意入堆操作时 有个优化!
4+
T: O(n*lg(k)) S:O(k)
5+
'''
6+
def findKthLargest0(nums: List[int], k: int) -> int:
7+
if not nums:
8+
return 0
9+
heap = []
10+
import heapq # 默认是min heap
11+
for num in nums:
12+
if len(heap) < k:
13+
heapq.heappush(heap, num)
14+
elif num > heap[0]: # 优化点!只有在当前num>堆顶时 才进行pushpop操作
15+
# 如果num<=堆顶 则num一定不会是第k大(堆顶比num更有可能是)
16+
heapq.heappushpop(heap, num)
17+
return heap[0] # 堆顶元素是k个在堆里元素中 最小的 -> 第k大
18+
19+
'''
20+
解法2: quick select
21+
随意选一个pivot number, move all smaller to left of pivot, all larger to right of pivot.
22+
T: avg O(n) worst O(n^2) S: O(h) due to recursion call.
23+
'''
24+
def findKthLargest1(nums: List[int], k: int) -> int:
25+
if not nums:
26+
return 0
27+
k = len(nums) - k
28+
return quickSelect(nums, k, 0, len(nums) - 1)
29+
30+
def quickSelect(nums, k, start, end) -> int:
31+
pivot = nums[start]
32+
left, right = start, end # 要重新assign pointer, 因为需要left right不断移动
33+
while left <= right:
34+
while left <= right and nums[left] < pivot:
35+
left += 1
36+
while left <= right and nums[right] > pivot:
37+
right -= 1
38+
if left <= right:
39+
nums[left], nums[right] = nums[right], nums[left]
40+
left += 1
41+
right -= 1
42+
# 结束的时候left在右 right在左[start, right, left, end]
43+
if k >= left:
44+
quickSelect(nums, k, left, end)
45+
if k <= right:
46+
quickSelect(nums, k, start, right)
47+
return nums[k]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
from typing import Optional, List, collections
3+
4+
class TreeNode:
5+
def __init__(self, val = 0, left = None, right = None):
6+
self.val = val
7+
self.left = left
8+
self.right = right
9+
10+
def verticalOrder(root: Optional[TreeNode]) -> List[List[int]]:
11+
if not root:
12+
return []
13+
14+
ret = []
15+
# {col_idx, [list of nodes with column idx as col_idx]}
16+
node_dict = collections.defaultdict(list) # dict不是Python keywords, 但不推荐作为变量名
17+
queue = collections.deque([(root, 0)]) # 括号里是[(x,y)]形式. root col_idx as 0
18+
min_col, max_col = 0, 0
19+
20+
while queue:
21+
node, idx = queue.popleft() # front is at the right-end
22+
min_col = min(idx, min_col)
23+
max_col = max(idx, max_col)
24+
if node.left:
25+
queue.append((node.left, idx - 1))
26+
if node.right:
27+
queue.append((node.right, idx + 1))
28+
node_dict[idx].append(node.val)
29+
30+
for i in range(min_col, max_col + 1):
31+
ret.append(node_dict[i])
32+
33+
return ret

Meta/LC408 Valid Word Abbreviation.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'''
2+
A string can be abbreviated by replacing any number of non-adjacent, non-empty substrings with their lengths. The lengths should not have leading zeros.
3+
4+
For example, a string such as "substitution" could be abbreviated as (but not limited to):
5+
6+
"s10n" ("s ubstitutio n")
7+
"sub4u4" ("sub stit u tion")
8+
"12" ("substitution")
9+
"su3i1u2on" ("su bst i t u ti on")
10+
"substitution" (no substrings replaced)
11+
The following are not valid abbreviations:
12+
13+
"s55n" ("s ubsti tutio n", the replaced substrings are adjacent)
14+
"s010n" (has leading zeros)
15+
"s0ubstitution" (replaces an empty substring)
16+
Given a string word and an abbreviation abbr, return whether the string matches the given abbreviation.
17+
18+
A substring is a contiguous non-empty sequence of characters within a string.
19+
20+
Example 1:
21+
22+
Input: word = "internationalization", abbr = "i12iz4n"
23+
Output: true
24+
Explanation: The word "internationalization" can be abbreviated as "i12iz4n" ("i nternational iz atio n").
25+
'''
26+
27+
'''
28+
solution: two pointers T: O(n) S: O(n)for tmp字符串构建
29+
'''
30+
31+
def validWordAbbreviation(word: str, abbr: str) -> bool:
32+
if len(word) < len(abbr): return False # word比abbr还短 一定不会匹配
33+
34+
i, j = 0, 0
35+
while i < len(word) and j < len(abbr):
36+
if word[i] != abbr[j]:
37+
if abbr[j] == '0' or not abbr[j].isdigit():
38+
return False
39+
40+
tmp = '' # 截取abbr当前的数字段
41+
while j < len(abbr) and abbr[j].isdigit():
42+
tmp += abbr[j]
43+
j += 1
44+
i += int(tmp) # i跳过长度为tmp的字符串
45+
else: # 两个字符相等 各进一步
46+
i += 1
47+
j += 1
48+
return i == len(word) and j == len(abbr) # 一定要都恰好走到最后一个

Meta/LC680 Valid Palindrome II.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'''
2+
Given a string s, return true if the s can be palindrome after deleting at most one character from it.
3+
Example 1:
4+
Input: s = "aba"
5+
Output: true
6+
'''
7+
8+
# time O(n) space O(1)
9+
def validPalindrome(s: str) -> bool:
10+
if not s:
11+
return True
12+
13+
left, right = 0, len(s) - 1
14+
while left < right:
15+
if s[left] != s[right]: # 要么左边跳过当前字符 要么右边跳过当前字符
16+
if is_palindrome(left + 1, right, s) or is_palindrome(left, right - 1, s):
17+
return True
18+
else: # 只有一次跳过的机会.尝试跳过不成功,直接return False
19+
return False
20+
else:
21+
left += 1
22+
right -= 1
23+
return True
24+
25+
def is_palindrome(i, j, s) -> bool:
26+
while i < j:
27+
if s[i] != s[j]:
28+
return False
29+
i += 1
30+
j -= 1
31+
return True

0 commit comments

Comments
 (0)