From 47835c3467814b0e6230a6576496597f8c784631 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Sat, 18 Mar 2023 18:06:45 +0530 Subject: [PATCH 01/14] 1472. Design Browser History --- python/design_browser_history.py | 18 ++++++++++++++++++ src/DesignBrowserHistory.java | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 python/design_browser_history.py create mode 100644 src/DesignBrowserHistory.java diff --git a/python/design_browser_history.py b/python/design_browser_history.py new file mode 100644 index 0000000..9542330 --- /dev/null +++ b/python/design_browser_history.py @@ -0,0 +1,18 @@ +class BrowserHistory: + + def __init__(self, homepage: str): + self.history = [homepage] + self.ptr = 0 + + def visit(self, url: str) -> None: + self.ptr += 1 + self.history = self.history[:self.ptr] + self.history.append(url) + + def back(self, steps: int) -> str: + self.ptr = max(0, self.ptr - steps) + return self.history[self.ptr] + + def forward(self, steps: int) -> str: + self.ptr = min(len(self.history) - 1, self.ptr + steps) + return self.history[self.ptr] \ No newline at end of file diff --git a/src/DesignBrowserHistory.java b/src/DesignBrowserHistory.java new file mode 100644 index 0000000..fe4258f --- /dev/null +++ b/src/DesignBrowserHistory.java @@ -0,0 +1,26 @@ +class BrowserHistory { + private List history; + private int ptr; + + public BrowserHistory(String homepage) { + this.history = new ArrayList<>(); + this.history.add(homepage); + this.ptr = 0; + } + + public void visit(String url) { + this.ptr++; + this.history = this.history.subList(0, this.ptr); + this.history.add(url); + } + + public String back(int steps) { + this.ptr = Math.max(0, this.ptr - steps); + return this.history.get(this.ptr); + } + + public String forward(int steps) { + this.ptr = Math.min(this.history.size() - 1, this.ptr + steps); + return this.history.get(this.ptr); + } +} \ No newline at end of file From 31b4c4aa377d8aeeef8b0068ed1c61e46ab7c6df Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Sun, 19 Mar 2023 23:47:31 +0530 Subject: [PATCH 02/14] problem 211: Design Add and Search Words Data Structure --- ...ign_add_and_search_words_data_structure.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 python/design_add_and_search_words_data_structure.py diff --git a/python/design_add_and_search_words_data_structure.py b/python/design_add_and_search_words_data_structure.py new file mode 100644 index 0000000..15c980b --- /dev/null +++ b/python/design_add_and_search_words_data_structure.py @@ -0,0 +1,37 @@ +class Trienode: + def __init__(self): + self.children = {} + self.word = False + +class WordDictionary: + + def __init__(self): + self.root = Trienode() + + + def addWord(self, word: str) -> None: + ptr = self.root + for ch in word: + if ch not in ptr.children: + ptr.children[ch] = Trienode() + ptr = ptr.children[ch] + ptr.word = True + + + def search(self, word: str) -> bool: + def dfs(j, root): + curr = root + for i in range(j, len(word)): + ch = word[i] + if ch == ".": + for child in curr.children.values(): + if dfs(i+1, child): + return True + return False + else: + if ch not in curr.children: + return False + curr = curr.children[ch] + return curr.word + return dfs(0, self.root) + From 4ab29f1089388bad47876a5ed6196f9af2439c5b Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Sun, 19 Mar 2023 23:55:34 +0530 Subject: [PATCH 03/14] added new lines at end of files --- python/design_add_and_search_words_data_structure.py | 1 - python/design_browser_history.py | 2 +- src/DesignBrowserHistory.java | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/python/design_add_and_search_words_data_structure.py b/python/design_add_and_search_words_data_structure.py index 15c980b..23326bf 100644 --- a/python/design_add_and_search_words_data_structure.py +++ b/python/design_add_and_search_words_data_structure.py @@ -34,4 +34,3 @@ def dfs(j, root): curr = curr.children[ch] return curr.word return dfs(0, self.root) - diff --git a/python/design_browser_history.py b/python/design_browser_history.py index 9542330..918683a 100644 --- a/python/design_browser_history.py +++ b/python/design_browser_history.py @@ -15,4 +15,4 @@ def back(self, steps: int) -> str: def forward(self, steps: int) -> str: self.ptr = min(len(self.history) - 1, self.ptr + steps) - return self.history[self.ptr] \ No newline at end of file + return self.history[self.ptr] diff --git a/src/DesignBrowserHistory.java b/src/DesignBrowserHistory.java index fe4258f..ded6e65 100644 --- a/src/DesignBrowserHistory.java +++ b/src/DesignBrowserHistory.java @@ -23,4 +23,4 @@ public String forward(int steps) { this.ptr = Math.min(this.history.size() - 1, this.ptr + steps); return this.history.get(this.ptr); } -} \ No newline at end of file +} From 49903da3213d49566e4cb7b69f4214d8ca1951ab Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Mon, 20 Mar 2023 23:08:13 +0530 Subject: [PATCH 04/14] 208: implement Trie (Prefix Tree) --- python/trie.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 python/trie.py diff --git a/python/trie.py b/python/trie.py new file mode 100644 index 0000000..8559761 --- /dev/null +++ b/python/trie.py @@ -0,0 +1,34 @@ +class TrieNode: + def __init__(self): + self.children = {} + self.is_word = False + +class Trie: + + def __init__(self): + self.root = TrieNode() + + def insert(self, word: str) -> None: + node = self.root + for char in word: + if char not in node.children: + node.children[char] = TrieNode() + node = node.children[char] + node.is_word = True + + def search(self, word: str) -> bool: + node = self.root + for char in word: + if char not in node.children: + return False + node = node.children[char] + return node.is_word + + + def startsWith(self, prefix: str) -> bool: + node = self.root + for char in prefix: + if char not in node.children: + return False + node = node.children[char] + return True From 89a75cf0be6e768ddfa437c043268d76b4334840 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Wed, 22 Mar 2023 00:25:37 +0530 Subject: [PATCH 05/14] 2348: Number of Zero-Filled Subarrays --- python/number_of_zero_filled_subarrays.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 python/number_of_zero_filled_subarrays.py diff --git a/python/number_of_zero_filled_subarrays.py b/python/number_of_zero_filled_subarrays.py new file mode 100644 index 0000000..0db2239 --- /dev/null +++ b/python/number_of_zero_filled_subarrays.py @@ -0,0 +1,15 @@ +class Solution: + def zeroFilledSubarray(self, nums) -> int: + count = 0 + i = 0 + while i < len(nums): + if nums[i] == 0: + j = i + while j < len(nums) and nums[j] == 0: + j += 1 + count += (j - i) * (j - i + 1) // 2 + i = j + else: + i = i+1 + + return count From 4bbca0152bc68de335bc6414d3fc5049e88b0cde Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Wed, 22 Mar 2023 00:30:59 +0530 Subject: [PATCH 06/14] 218: The Skyline Problem --- python/the_skyline_problem.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 python/the_skyline_problem.py diff --git a/python/the_skyline_problem.py b/python/the_skyline_problem.py new file mode 100644 index 0000000..40c324d --- /dev/null +++ b/python/the_skyline_problem.py @@ -0,0 +1,25 @@ +import bisect + +class Solution: + def getSkyline(self, buildings): + h = [] + for b in buildings: + h.append((b[0], -b[2])) + h.append((b[1], b[2])) + + h.sort() + prev = cur = 0 + m = [0] + res = [] + + for i in h: + if i[1] < 0: + bisect.insort(m, -i[1]) + else: + m.remove(i[1]) + cur = max(m) + if cur != prev: + res.append([i[0], cur]) + prev = cur + + return res From 42bc4e0ce9897d285790d3fc3c5a6438ba234a2d Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Wed, 22 Mar 2023 14:15:12 +0530 Subject: [PATCH 07/14] 2492: Minimum Score of a Path Between Two Cities --- ...imum_score_of_a_path_between_two_cities.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 python/minimum_score_of_a_path_between_two_cities.py diff --git a/python/minimum_score_of_a_path_between_two_cities.py b/python/minimum_score_of_a_path_between_two_cities.py new file mode 100644 index 0000000..8741e86 --- /dev/null +++ b/python/minimum_score_of_a_path_between_two_cities.py @@ -0,0 +1,30 @@ +from collections import deque + +class Solution: + def __init__(self): + self.min_dist = 1e14 + + def minScore(self, n: int, roads) -> int: + graph = {} + vis = [False]*n + for x, y, d in roads: + if x in graph: + graph[x].append((y, d)) + else: + graph[x] = [(y, d)] + if y in graph: + graph[y].append((x, d)) + else: + graph[y] = [(x, d)] + + visited = set() + queue = deque([1]) + + while queue: + node = queue.popleft() + for adj, score in graph[node]: + if adj not in visited: + queue.append(adj) + visited.add(adj) + self.min_dist = min(self.min_dist, score) + return self.min_dist From 98fc01f2c1b55b2c2e9bee58657f6214994e2945 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Wed, 22 Mar 2023 14:39:51 +0530 Subject: [PATCH 08/14] added Links + Time & Space Complexity --- python/minimum_score_of_a_path_between_two_cities.py | 4 ++++ python/number_of_zero_filled_subarrays.py | 4 ++++ python/the_skyline_problem.py | 4 ++++ python/trie.py | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/python/minimum_score_of_a_path_between_two_cities.py b/python/minimum_score_of_a_path_between_two_cities.py index 8741e86..37cfc10 100644 --- a/python/minimum_score_of_a_path_between_two_cities.py +++ b/python/minimum_score_of_a_path_between_two_cities.py @@ -1,3 +1,7 @@ +# https://leetcode.com/problems/minimum-score-of-a-path-between-two-cities/ +# T: O(N + M) where N is the number of nodes and M is the number of edges +# S: O(N + M) where N is the number of nodes and M is the number of edges + from collections import deque class Solution: diff --git a/python/number_of_zero_filled_subarrays.py b/python/number_of_zero_filled_subarrays.py index 0db2239..1438c11 100644 --- a/python/number_of_zero_filled_subarrays.py +++ b/python/number_of_zero_filled_subarrays.py @@ -1,3 +1,7 @@ +# https://leetcode.com/problems/number-of-zero-filled-subarrays/ +# T: O(N) where N is the length of nums +# S: O(1) + class Solution: def zeroFilledSubarray(self, nums) -> int: count = 0 diff --git a/python/the_skyline_problem.py b/python/the_skyline_problem.py index 40c324d..91e2aad 100644 --- a/python/the_skyline_problem.py +++ b/python/the_skyline_problem.py @@ -1,3 +1,7 @@ +# https://leetcode.com/problems/the-skyline-problem/ +# T: O(NlogN) where N is the number of buildings +# S: O(N) where N is the number of buildings + import bisect class Solution: diff --git a/python/trie.py b/python/trie.py index 8559761..ef9b4ed 100644 --- a/python/trie.py +++ b/python/trie.py @@ -1,3 +1,7 @@ +# https://leetcode.com/problems/implement-trie-prefix-tree/ +# T: O(N) where N is the length of the word +# S: O(MN) where M is the number of words, N is the maximum length of the word + class TrieNode: def __init__(self): self.children = {} From ba0eaca736096a0fdb3b6c6d1952c9c260ab6eb6 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Thu, 23 Mar 2023 15:49:17 +0530 Subject: [PATCH 09/14] 1319: Number of Operations to Make Network Connected --- ...of_operations_to_make_network_connected.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 python/no_of_operations_to_make_network_connected.py diff --git a/python/no_of_operations_to_make_network_connected.py b/python/no_of_operations_to_make_network_connected.py new file mode 100644 index 0000000..f5cec37 --- /dev/null +++ b/python/no_of_operations_to_make_network_connected.py @@ -0,0 +1,35 @@ +# https://leetcode.com/problems/number-of-operations-to-make-network-connected/description/ +# T: O(M) where M is the number of connections +# S: O(N) where N is the number of nodes + +class Solution: + def makeConnected(self, n, connections) -> int: + if len(connections) < n-1: + return -1 + if n == 1: + return 0 + graph = {} + for a, b in connections: + if a in graph: + graph[a].append(b) + else: + graph[a] = [b] + + if b in graph: + graph[b].append(a) + else: + graph[b] = [a] + + visited = [0] * n + + def dfs(node): + if visited[node]: + return 0 + visited[node] = 1 + if node in graph: + for num in graph[node]: + dfs(num) + return 1 + + + return sum(dfs(node) for node in range(n)) - 1 From 53bb26314fc4a99392836e85b8f37f3f70494fb0 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Thu, 23 Mar 2023 17:08:46 +0530 Subject: [PATCH 10/14] 200: Number of Islands --- python/number_of_islands.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 python/number_of_islands.py diff --git a/python/number_of_islands.py b/python/number_of_islands.py new file mode 100644 index 0000000..76d2814 --- /dev/null +++ b/python/number_of_islands.py @@ -0,0 +1,24 @@ +# https://leetcode.com/problems/number-of-islands/description/ +# T: O(MN) where M is the number of rows and N is the number of columns. +# S: O(MN) where M is the number of rows and N is the number of columns. + +def numIslands(self, grid): + if not grid: + return 0 + + count = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == '1': + self.dfs(grid, i, j) + count += 1 + return count + +def dfs(self, grid, i, j): + if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1': + return + grid[i][j] = '#' + self.dfs(grid, i+1, j) + self.dfs(grid, i-1, j) + self.dfs(grid, i, j+1) + self.dfs(grid, i, j-1) From 205425aed06cb2b604628c7f582a5b2ef90141e2 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Fri, 24 Mar 2023 21:35:13 +0530 Subject: [PATCH 11/14] 1466: Reorder Routes Reorder Routes to Make All Paths Lead to the City Zero --- ...tes_to_make_all_paths_lead_to_city_zero.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 python/reorder_routes_to_make_all_paths_lead_to_city_zero.py diff --git a/python/reorder_routes_to_make_all_paths_lead_to_city_zero.py b/python/reorder_routes_to_make_all_paths_lead_to_city_zero.py new file mode 100644 index 0000000..1c89b52 --- /dev/null +++ b/python/reorder_routes_to_make_all_paths_lead_to_city_zero.py @@ -0,0 +1,26 @@ +# https://leetcode.com/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero/description/ +# T: O(N) where N is the number of nodes in the graph +# S: O(N) where N is the number of nodes in the graph + +class Solution: + def __init__(self): + self.reorders = 0 + + def minReorder(self, n, connections): + edges = {(u, v) for u, v in connections} + graph = {i:[] for i in range(n)} + for u, v in connections: + graph[u].append(v) + graph[v].append(u) + visit = set() + visit.add(0) + def dfs(graph, edges, visit, city): + for node in graph[city]: + if node in visit: + continue + if (node, city) not in edges: + self.reorders+=1 + visit.add(node) + dfs(graph, edges, visit, node) + dfs(graph, edges, visit, 0) + return self.reorders From 022d3e6cf960b8be0ea65036cebcded46e0652c9 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Sat, 25 Mar 2023 15:57:37 +0530 Subject: [PATCH 12/14] 2316: Count Unreachable Pairs Count Unreachable Pairs of Nodes in an Undirected Graph --- ...e_pair_of_node_in_an_undirectable_graph.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 python/count_unreachable_pair_of_node_in_an_undirectable_graph.py diff --git a/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py b/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py new file mode 100644 index 0000000..22fde48 --- /dev/null +++ b/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py @@ -0,0 +1,49 @@ +# https://leetcode.com/problems/count-unreachable-pairs-of-nodes-in-an-undirected-graph/description/ +# T: O(N + E) where N is the number of nodes and E is the number of edges +# S: O(N + E) where N is the number of nodes and E is the number of edges + +from collections import defaultdict +class Solution: + def __init__(self): + self.graph = defaultdict(list) + self.visited = set() + self.n = 0 + + def add_edge(self, u, v): + self.graph[u].append(v) + self.graph[v].append(u) + + def dfs(self, v, component): + self.visited.add(v) + component.append(v) + for neighbor in self.graph[v]: + if neighbor not in self.visited: + self.dfs(neighbor, component) + + def find_components(self): + components = [] + for v in range(self.n): + if v not in self.visited: + component = [] + self.dfs(v, component) + components.append(component) + + return components + + def countPairs(self, n, edges): + for u, v in edges: + self.add_edge(u, v) + self.n = n + component_lengths = [] + components = self.find_components() + for component in components: + component_lengths.append(len(component)) + print(components, component_lengths) + + k = sum(component_lengths) + sol = 0 + for l in component_lengths: + sol+=((k-l)*l) + sol = sol//2 + + return sol From 2f583328de70d822d2e16cc736e082e9edadc708 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Sat, 25 Mar 2023 16:11:06 +0530 Subject: [PATCH 13/14] [deleted file] creating branch for multiple pull requests --- ...e_pair_of_node_in_an_undirectable_graph.py | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 python/count_unreachable_pair_of_node_in_an_undirectable_graph.py diff --git a/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py b/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py deleted file mode 100644 index 22fde48..0000000 --- a/python/count_unreachable_pair_of_node_in_an_undirectable_graph.py +++ /dev/null @@ -1,49 +0,0 @@ -# https://leetcode.com/problems/count-unreachable-pairs-of-nodes-in-an-undirected-graph/description/ -# T: O(N + E) where N is the number of nodes and E is the number of edges -# S: O(N + E) where N is the number of nodes and E is the number of edges - -from collections import defaultdict -class Solution: - def __init__(self): - self.graph = defaultdict(list) - self.visited = set() - self.n = 0 - - def add_edge(self, u, v): - self.graph[u].append(v) - self.graph[v].append(u) - - def dfs(self, v, component): - self.visited.add(v) - component.append(v) - for neighbor in self.graph[v]: - if neighbor not in self.visited: - self.dfs(neighbor, component) - - def find_components(self): - components = [] - for v in range(self.n): - if v not in self.visited: - component = [] - self.dfs(v, component) - components.append(component) - - return components - - def countPairs(self, n, edges): - for u, v in edges: - self.add_edge(u, v) - self.n = n - component_lengths = [] - components = self.find_components() - for component in components: - component_lengths.append(len(component)) - print(components, component_lengths) - - k = sum(component_lengths) - sol = 0 - for l in component_lengths: - sol+=((k-l)*l) - sol = sol//2 - - return sol From aaf1d6eea1c9fc0a28967a6ecede012ecd3a8af5 Mon Sep 17 00:00:00 2001 From: sumanth-botlagunta Date: Mon, 27 Mar 2023 23:20:46 +0530 Subject: [PATCH 14/14] solves 64: Minimum Path Sum --- python/minimum_path_sum.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 python/minimum_path_sum.py diff --git a/python/minimum_path_sum.py b/python/minimum_path_sum.py new file mode 100644 index 0000000..af71159 --- /dev/null +++ b/python/minimum_path_sum.py @@ -0,0 +1,19 @@ +# https://leetcode.com/problems/minimum-path-sum/ +# T: O(m*n) where n is the number of rows and m is the number of columns +# S: O(1) + +class Solution: + def minPathSum(self, grid): + rows, columns = len(grid), len(grid[0]) + + for column in range(columns - 2, -1, -1): + grid[rows - 1][column] += grid[rows - 1][column + 1] + + for row in range(rows - 2, -1, -1): + grid[row][columns - 1] += grid[row + 1][columns - 1] + + for row in range(rows - 2, -1, -1): + for column in range(columns - 2, -1, -1): + grid[row][column] += min(grid[row + 1][column], grid[row][column + 1]) + + return grid[0][0]