-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5598e22
commit 0bc3d9b
Showing
12 changed files
with
632 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Given a reference of a node in a connected undirected graph. | ||
# Return a deep copy (clone) of the graph. | ||
# Each node in the graph contains a value (int) and a list (List[Node]) of its neighbors. | ||
# | ||
# class Node { | ||
# public int val; | ||
# public List<Node> neighbors; | ||
# } | ||
# | ||
# | ||
# Test case format: | ||
# | ||
# For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with val == 1, the second node with val == 2, and so on. The graph is represented in the test case using an adjacency list. | ||
# An adjacency list is a collection of unordered lists used to represent a finite graph. Each list describes the set of neighbors of a node in the graph. | ||
# The given node will always be the first node with val = 1. You must return the copy of the given node as a reference to the cloned graph. | ||
# | ||
# Example 1: | ||
# | ||
# Input: adjList = [[2,4],[1,3],[2,4],[1,3]] | ||
# Output: [[2,4],[1,3],[2,4],[1,3]] | ||
# Explanation: There are 4 nodes in the graph. | ||
# 1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4). | ||
# 2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3). | ||
# 3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4). | ||
# 4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3). | ||
# | ||
# Example 2: | ||
# | ||
# Input: adjList = [[]] | ||
# Output: [[]] | ||
# Explanation: Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors. | ||
# | ||
# Example 3: | ||
# | ||
# Input: adjList = [] | ||
# Output: [] | ||
# Explanation: This an empty graph, it does not have any nodes. | ||
# | ||
# Constraints: | ||
# | ||
# The number of nodes in the graph is in the range [0, 100]. | ||
# 1 <= Node.val <= 100 | ||
# Node.val is unique for each node. | ||
# There are no repeated edges and no self-loops in the graph. | ||
# The Graph is connected and all nodes can be visited starting from the given node. | ||
|
||
|
||
""" | ||
# Definition for a Node. | ||
class Node: | ||
def __init__(self, val = 0, neighbors = None): | ||
self.val = val | ||
self.neighbors = neighbors if neighbors is not None else [] | ||
""" | ||
|
||
|
||
# DFS | ||
class Solution: | ||
def cloneGraph(self, node: "Node") -> "Node": | ||
if not node: | ||
return None | ||
|
||
cache = {} | ||
|
||
def clone(u0): | ||
if u0 in cache: | ||
return cache[u0] | ||
u1 = Node(u0.val) | ||
cache[u0] = u1 | ||
for v in u0.neighbors: | ||
u1.neighbors.append(clone(v)) | ||
return u1 | ||
|
||
return clone(node) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become: | ||
# | ||
# [4,5,6,7,0,1,2] if it was rotated 4 times. | ||
# [0,1,2,4,5,6,7] if it was rotated 7 times. | ||
# Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]]. | ||
# | ||
# Given the sorted rotated array nums of unique elements, return the minimum element of this array. | ||
# | ||
# You must write an algorithm that runs in O(log n) time. | ||
# | ||
# Example 1: | ||
# | ||
# Input: nums = [3,4,5,1,2] | ||
# Output: 1 | ||
# Explanation: The original array was [1,2,3,4,5] rotated 3 times. | ||
# | ||
# Example 2: | ||
# | ||
# Input: nums = [4,5,6,7,0,1,2] | ||
# Output: 0 | ||
# Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times. | ||
# | ||
# Example 3: | ||
# | ||
# Input: nums = [11,13,15,17] | ||
# Output: 11 | ||
# Explanation: The original array was [11,13,15,17] and it was rotated 4 times. | ||
# | ||
# Constraints: | ||
# | ||
# n == nums.length | ||
# 1 <= n <= 5000 | ||
# -5000 <= nums[i] <= 5000 | ||
# All the integers of nums are unique. | ||
# nums is sorted and rotated between 1 and n times. | ||
|
||
|
||
# 1) Binary Search | ||
class Solution: | ||
def findMin(self, nums: List[int]) -> int: | ||
if len(nums) == 1: | ||
return nums[0] | ||
|
||
l = 0 | ||
r = len(nums) - 1 | ||
|
||
# e.g. 1 < 2 < 3 < 4 < 5 sorted array, so return nums[0] | ||
if nums[r] > nums[0]: | ||
return nums[0] | ||
|
||
while l <= r: | ||
m = (l + r) // 2 | ||
|
||
if nums[m - 1] > nums[m]: | ||
return nums[m] | ||
if nums[m] > nums[m + 1]: | ||
return nums[m + 1] | ||
|
||
if nums[m] > nums[0]: | ||
l = m + 1 | ||
else: | ||
r = m - 1 | ||
|
||
|
||
# 2) Binary Search | ||
class Solution: | ||
def findMin(self, nums: List[int]) -> int: | ||
l = 0 | ||
r = len(nums) - 1 | ||
while l < r: | ||
m = (l + r) // 2 | ||
if nums[m] > nums[r]: | ||
l = m + 1 | ||
else: | ||
r = m | ||
return nums[l] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# You are given an m x n grid rooms initialized with these three possible values. | ||
# | ||
# -1 A wall or an obstacle. | ||
# 0 A gate. | ||
# INF Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. | ||
# | ||
# Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. | ||
# | ||
# Example 1: | ||
# | ||
# Input: rooms = [[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]] | ||
# Output: [[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]] | ||
# | ||
# Example 2: | ||
# | ||
# Input: rooms = [[-1]] | ||
# Output: [[-1]] | ||
# | ||
# Constraints: | ||
# | ||
# m == rooms.length | ||
# n == rooms[i].length | ||
# 1 <= m, n <= 250 | ||
# rooms[i][j] is -1, 0, or 2^31 - 1. | ||
|
||
# BFS | ||
class Solution: | ||
def wallsAndGates(self, rooms: List[List[int]]) -> None: | ||
""" | ||
Do not return anything, modify rooms in-place instead. | ||
""" | ||
if not rooms: | ||
return | ||
|
||
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)] | ||
m, n = len(rooms), len(rooms[0]) | ||
|
||
q = [] | ||
for i in range(m): | ||
for j in range(n): | ||
if rooms[i][j] == 0: | ||
q.append((i, j)) | ||
|
||
while q: | ||
i, j = q.pop(0) | ||
for di, dj in dirs: | ||
x, y = i + di, j + dj | ||
if 0 <= x < m and 0 <= y < n and rooms[x][y] == 2147483647: | ||
rooms[x][y] = rooms[i][j] + 1 | ||
q.append((x, y)) | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window. | ||
# Implement the MovingAverage class: | ||
# | ||
# - MovingAverage(int size) Initializes the object with the size of the window size. | ||
# - double next(int val) Returns the moving average of the last size values of the stream. | ||
# | ||
# Example 1: | ||
# | ||
# Input | ||
# ["MovingAverage", "next", "next", "next", "next"] | ||
# [[3], [1], [10], [3], [5]] | ||
# Output | ||
# [null, 1.0, 5.5, 4.66667, 6.0] | ||
# | ||
# Explanation | ||
# MovingAverage movingAverage = new MovingAverage(3); | ||
# movingAverage.next(1); // return 1.0 = 1 / 1 | ||
# movingAverage.next(10); // return 5.5 = (1 + 10) / 2 | ||
# movingAverage.next(3); // return 4.66667 = (1 + 10 + 3) / 3 | ||
# movingAverage.next(5); // return 6.0 = (10 + 3 + 5) / 3 | ||
# | ||
# Constraints: | ||
# | ||
# 1 <= size <= 1000 | ||
# -105 <= val <= 105 | ||
# At most 104 calls will be made to next. | ||
|
||
|
||
# 1) Array | ||
# Time O(N) where N is the size of the moving window, since we need to retrieve NN elements from the queue at each invocation of next(val) function. | ||
# Space O(M), where M is the length of the queue which would grow at each invocation of the next(val) function. | ||
class MovingAverage: | ||
def __init__(self, size: int): | ||
self.size = size | ||
self.q = [] | ||
|
||
def next(self, val: int) -> float: | ||
self.q.append(val) | ||
# calculate the sum of the moving window | ||
window_sum = sum(self.q[-self.size :]) | ||
return window_sum / min(len(self.q), self.size) | ||
|
||
|
||
# 2) Double-ended Queue | ||
# Time O(1), as we explained in intuition. | ||
# Space O(N), where NN is the size of the moving window. | ||
class MovingAverage: | ||
def __init__(self, size: int): | ||
self.size = size | ||
self.q = [] | ||
# number of elements seen so far | ||
self.window_sum = 0 | ||
self.count = 0 | ||
|
||
def next(self, val: int) -> float: | ||
self.count += 1 | ||
# calculate the new sum by shifting the window | ||
self.q.append(val) | ||
tail = self.q.pop(0) if self.count > self.size else 0 | ||
self.window_sum = self.window_sum - tail + val | ||
return self.window_sum / min(self.size, self.count) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# You are given an integer array nums and an integer target. | ||
# You want to build an expression out of nums by adding one of the symbols '+' and '-' before each integer in nums and then concatenate all the integers. | ||
# For example, if nums = [2, 1], you can add a '+' before 2 and a '-' before 1 and concatenate them to build the expression "+2-1". | ||
# Return the number of different expressions that you can build, which evaluates to target. | ||
# | ||
# Example 1: | ||
# | ||
# Input: nums = [1,1,1,1,1], target = 3 | ||
# Output: 5 | ||
# Explanation: There are 5 ways to assign symbols to make the sum of nums be target 3. | ||
# -1 + 1 + 1 + 1 + 1 = 3 | ||
# +1 - 1 + 1 + 1 + 1 = 3 | ||
# +1 + 1 - 1 + 1 + 1 = 3 | ||
# +1 + 1 + 1 - 1 + 1 = 3 | ||
# +1 + 1 + 1 + 1 - 1 = 3 | ||
# | ||
# Example 2: | ||
# | ||
# Input: nums = [1], target = 1 | ||
# Output: 1 | ||
# | ||
# Constraints: | ||
# | ||
# 1 <= nums.length <= 20 | ||
# 0 <= nums[i] <= 1000 | ||
# 0 <= sum(nums[i]) <= 1000 | ||
# -1000 <= target <= 1000 | ||
|
||
# 1) DFS | ||
class Solution: | ||
def findTargetSumWays(self, nums: List[int], target: int) -> int: | ||
def find(i, t): | ||
if (i, t) in cache: | ||
return cache[(i, t)] | ||
count = 0 | ||
if i == len(nums): | ||
if t == 0: | ||
count = 1 | ||
else: | ||
count = find(i + 1, t - nums[i]) + find(i + 1, t + nums[i]) | ||
cache[(i, t)] = count | ||
return count | ||
|
||
cache = {} | ||
return find(0, target) | ||
|
||
|
||
# 2) DFS, similar to 1) | ||
from functools import cache | ||
|
||
|
||
class Solution: | ||
def findTargetSumWays(self, nums: List[int], target: int) -> int: | ||
@cache | ||
def find(i, t): | ||
if i == len(nums): | ||
return 1 if t == 0 else 0 | ||
return find(i + 1, t - nums[i]) + find(i + 1, t + nums[i]) | ||
|
||
return find(0, target) |
Oops, something went wrong.