Skip to content

Commit

Permalink
Add problems from Weekly Contest 178
Browse files Browse the repository at this point in the history
  • Loading branch information
lydxlx1 committed Mar 8, 2020
1 parent 03d60b7 commit 64c7d77
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ I will keep updating the list and feel free to share any of your thoughts!

| # | Title | Solutions |
|----|---|---|
||[Minimum Cost to Make at Least One Valid Path in a Grid][lc0079_t]|\[ [SSSP][lc0079] \]|
||[Linked List in Binary Tree][lc0078_t]|\[ [DFS][lc0078] \]|
||[Rank Teams by Votes][lc0077_t]|\[ [Radix Sort][lc0077] \]|
||[How Many Numbers Are Smaller Than the Current Number][lc0076_t]|\[ [Counting Sort][lc0076] \]|
||[Largest Multiple of Three][lc0075_t]|\[ [Math][lc0075] \]|
||[Closest Divisors][lc0074_t]|\[ [Enumeration][lc0074] \]|
||[Validate Binary Tree Nodes][lc0073_t]|\[ [DFS][lc0073] \]|
Expand Down Expand Up @@ -2259,3 +2263,11 @@ I will keep updating the list and feel free to share any of your thoughts!
[lc0074]: https://github.com/lydxlx1/LeetCode/blob/master/src/closest-divisors.py
[lc0075_t]: https://leetcode.com/problems/largest-multiple-of-three/
[lc0075]: https://github.com/lydxlx1/LeetCode/blob/master/src/largest-multiple-of-three.py
[lc0076_t]: https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/
[lc0076]: https://github.com/lydxlx1/LeetCode/blob/master/src/how-many-numbers-are-smaller-than-the-current-number.py
[lc0077_t]: https://leetcode.com/contest/weekly-contest-178/problems/rank-teams-by-votes/
[lc0077]: https://github.com/lydxlx1/LeetCode/blob/master/src/rank-teams-by-votes.py
[lc0078_t]: https://leetcode.com/problems/linked-list-in-binary-tree/
[lc0078]: https://github.com/lydxlx1/LeetCode/blob/master/src/linked-list-in-binary-tree.py
[lc0079_t]: https://leetcode.com/problems/minimum-cost-to-make-at-least-one-valid-path-in-a-grid/
[lc0079]: https://github.com/lydxlx1/LeetCode/blob/master/src/minimum-cost-to-make-at-least-one-valid-path-in-a-grid.py
20 changes: 20 additions & 0 deletions src/how-many-numbers-are-smaller-than-the-current-number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""1365. How Many Numbers Are Smaller Than the Current Number
Since each number is within the range [0, 100], we can use a counting sort based approach.
1. Do a linear-time counting.
2. Compute the prefix sum.
3. Answer each query in O(1) time.
Time: O(n)
Space: O(100)
"""


class Solution:
def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]:
cnt = [0] * 101
for i in nums:
cnt[i] += 1
for i in range(1, 101):
cnt[i] += cnt[i - 1]
return [cnt[i - 1] if i - 1 >= 0 else 0 for i in nums]
43 changes: 43 additions & 0 deletions src/linked-list-in-binary-tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""1367. Linked List in Binary Tree
It is hard to solve the problem in a top-down fashion since each tree node can have two choices.
However, since each node has a unique parent, the upwards paths ending at any node are also unique (by its length).
This suggests a DFS approach, where we just need to check whether the last m nodes on the stack match the given listed list at any time.
Time: O(mn)
Space: O(m + h)
m = linked list size, n = binary tree size, h = binary tree height
"""


class ListNode:
def __init__(self, x):
self.val = x
self.next = None


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def isSubPath(self, head: ListNode, root: TreeNode) -> bool:
target = []
while head:
target.append(head.val)
head = head.next

def dfs(root, path):
if len(path) >= len(target) and path[-len(target):] == target:
return True
if not root:
return False
path.append(root.val)
if dfs(root.left, path) or dfs(root.right, path):
return True
path.pop()
return False
return dfs(root, [])
45 changes: 45 additions & 0 deletions src/minimum-cost-to-make-at-least-one-valid-path-in-a-grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""1368. Minimum Cost to Make at Least One Valid Path in a Grid
Shortest Path
Build the graph
- For each grid cell, create four directed edges to its neighbors (if exist).
- The weight of the edge is 0 if the edge direction matches with the number in cell, otherwise the weight is 1.
This means each cell will have exactly one outgoing edge with 0 weight, and two or three outgoing edges with weight equal to 1.o
- Then, the length of the shortest path from top-left to bottom-right will be the answer.
Correctness
Time: O(mn log (mn)), which can be further optimized to O(mn).
This is because weights of edges in this graph are either 0 or 1, so we can compute the shortest path using BFS with a Deque.
Formally, we insert to the head of the queue if the edge weight is 0 and insert to the tail of the queue if weight is 1.
Space: O(mn)
"""

from sortedcontainers import SortedList
from typing import List


class Solution:
def minCost(self, grid: List[List[int]]) -> int:
dx = [None, 0, 0, 1, -1]
dy = [None, 1, -1, 0, 0]

dist = {(0, 0): 0}
queue = SortedList([(0, 0, 0)])
while queue:
d, i, j = queue.pop(0)
if i == len(grid) - 1 and j == len(grid[0]) - 1:
return d
for k in [1, 2, 3, 4]:
ii = i + dx[k]
jj = j + dy[k]
if 0 <= ii < len(grid) and 0 <= jj < len(grid[0]):
dd = d + (1 if grid[i][j] != k else 0)
if (ii, jj) not in dist or dd < dist[ii, jj]:
dist[ii, jj] = dd
queue.add((dd, ii, jj))
return -1
19 changes: 19 additions & 0 deletions src/rank-teams-by-votes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""1366. Rank Teams by Votes
Radix Sort
Assume there are m rounds of voting, we can solve this problem by a radix sort (from the m-th round to the first round).
Time: O(m * (26 log 26)), which can be further optimized to O(26m) using counting sort.
Space: O(26)
"""
from collections import Counter
from typing import List


class Solution:
def rankTeams(self, votes: List[str]) -> str:
a = sorted(list(votes[0]))
for col in range(len(votes[0]) - 1, -1, -1):
cnt = Counter(vote[col] for vote in votes)
a.sort(key=lambda ch: -cnt[ch])
return "".join(a)

0 comments on commit 64c7d77

Please sign in to comment.