From 358b28414a4acdfd73a623711d5e0f4742e17224 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 7 Mar 2025 14:04:54 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1257 No.1257.Smallest Common Region --- .../1257.Smallest Common Region/README.md | 170 ++++++++++++------ .../1257.Smallest Common Region/README_EN.md | 170 ++++++++++++------ .../1257.Smallest Common Region/Solution.cpp | 26 +-- .../1257.Smallest Common Region/Solution.go | 30 ++-- .../1257.Smallest Common Region/Solution.java | 26 ++- .../1257.Smallest Common Region/Solution.py | 25 +-- .../1257.Smallest Common Region/Solution.rs | 35 ++++ .../1257.Smallest Common Region/Solution.ts | 22 +++ 8 files changed, 352 insertions(+), 152 deletions(-) create mode 100644 solution/1200-1299/1257.Smallest Common Region/Solution.rs create mode 100644 solution/1200-1299/1257.Smallest Common Region/Solution.ts diff --git a/solution/1200-1299/1257.Smallest Common Region/README.md b/solution/1200-1299/1257.Smallest Common Region/README.md index f54bd638bf99d..f9a73717dfc2d 100644 --- a/solution/1200-1299/1257.Smallest Common Region/README.md +++ b/solution/1200-1299/1257.Smallest Common Region/README.md @@ -75,7 +75,11 @@ region2 = "New York" -### 方法一 +### 方法一:哈希表 + +我们可以用一个哈希表 $\textit{g}$ 来存储每个区域的父区域,然后从 $\textit{region1}$ 开始,不断向上找到所有的父区域,直到根区域,将这些区域放入集合 $\textit{s}$ 中。然后从 $\textit{region2}$ 开始,不断向上找到第一个在 $\textit{s}$ 中的区域,即为最小公共区域。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为区域列表 $\textit{regions}$ 的长度。 @@ -86,19 +90,20 @@ class Solution: def findSmallestRegion( self, regions: List[List[str]], region1: str, region2: str ) -> str: - m = {} - for region in regions: - for r in region[1:]: - m[r] = region[0] + g = {} + for r in regions: + x = r[0] + for y in r[1:]: + g[y] = x s = set() - while m.get(region1): - s.add(region1) - region1 = m[region1] - while m.get(region2): - if region2 in s: - return region2 - region2 = m[region2] - return region1 + x = region1 + while x in g: + s.add(x) + x = g[x] + x = region2 + while x in g and x not in s: + x = g[x] + return x ``` #### Java @@ -106,24 +111,22 @@ class Solution: ```java class Solution { public String findSmallestRegion(List> regions, String region1, String region2) { - Map m = new HashMap<>(); - for (List region : regions) { - for (int i = 1; i < region.size(); ++i) { - m.put(region.get(i), region.get(0)); + Map g = new HashMap<>(); + for (var r : regions) { + String x = r.get(0); + for (String y : r.subList(1, r.size())) { + g.put(y, x); } } Set s = new HashSet<>(); - while (m.containsKey(region1)) { - s.add(region1); - region1 = m.get(region1); + for (String x = region1; x != null; x = g.get(x)) { + s.add(x); } - while (m.containsKey(region2)) { - if (s.contains(region2)) { - return region2; - } - region2 = m.get(region2); + String x = region2; + while (g.get(x) != null && !s.contains(x)) { + x = g.get(x); } - return region1; + return x; } } ``` @@ -134,20 +137,22 @@ class Solution { class Solution { public: string findSmallestRegion(vector>& regions, string region1, string region2) { - unordered_map m; - for (auto& region : regions) - for (int i = 1; i < region.size(); ++i) - m[region[i]] = region[0]; + unordered_map g; + for (const auto& r : regions) { + string x = r[0]; + for (size_t i = 1; i < r.size(); ++i) { + g[r[i]] = x; + } + } unordered_set s; - while (m.count(region1)) { - s.insert(region1); - region1 = m[region1]; + for (string x = region1; !x.empty(); x = g[x]) { + s.insert(x); } - while (m.count(region2)) { - if (s.count(region2)) return region2; - region2 = m[region2]; + string x = region2; + while (!g[x].empty() && s.find(x) == s.end()) { + x = g[x]; } - return region1; + return x; } }; ``` @@ -156,24 +161,89 @@ public: ```go func findSmallestRegion(regions [][]string, region1 string, region2 string) string { - m := make(map[string]string) - for _, region := range regions { - for i := 1; i < len(region); i++ { - m[region[i]] = region[0] + g := make(map[string]string) + + for _, r := range regions { + x := r[0] + for _, y := range r[1:] { + g[y] = x } } + s := make(map[string]bool) - for region1 != "" { - s[region1] = true - region1 = m[region1] + for x := region1; x != ""; x = g[x] { + s[x] = true } - for region2 != "" { - if s[region2] { - return region2 - } - region2 = m[region2] + + x := region2 + for g[x] != "" && !s[x] { + x = g[x] } - return region1 + + return x +} +``` + +#### TypeScript + +```ts +function findSmallestRegion(regions: string[][], region1: string, region2: string): string { + const g: Record = {}; + + for (const r of regions) { + const x = r[0]; + for (const y of r.slice(1)) { + g[y] = x; + } + } + + const s: Set = new Set(); + for (let x: string = region1; x !== undefined; x = g[x]) { + s.add(x); + } + + let x: string = region2; + while (g[x] !== undefined && !s.has(x)) { + x = g[x]; + } + + return x; +} +``` + +#### Rust + +```rust +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn find_smallest_region(regions: Vec>, region1: String, region2: String) -> String { + let mut g: HashMap = HashMap::new(); + + for r in ®ions { + let x = &r[0]; + for y in &r[1..] { + g.insert(y.clone(), x.clone()); + } + } + + let mut s: HashSet = HashSet::new(); + let mut x = Some(region1); + while let Some(region) = x { + s.insert(region.clone()); + x = g.get(®ion).cloned(); + } + + let mut x = Some(region2); + while let Some(region) = x { + if s.contains(®ion) { + return region; + } + x = g.get(®ion).cloned(); + } + + String::new() + } } ``` diff --git a/solution/1200-1299/1257.Smallest Common Region/README_EN.md b/solution/1200-1299/1257.Smallest Common Region/README_EN.md index 0c3555319c989..d5b52f58e36c7 100644 --- a/solution/1200-1299/1257.Smallest Common Region/README_EN.md +++ b/solution/1200-1299/1257.Smallest Common Region/README_EN.md @@ -73,7 +73,11 @@ region2 = "New York" -### Solution 1 +### Solution 1: Hash Table + +We can use a hash table $\textit{g}$ to store the parent region of each region. Then, starting from $\textit{region1}$, we keep moving upwards to find all its parent regions until the root region, and store these regions in the set $\textit{s}$. Next, starting from $\textit{region2}$, we keep moving upwards to find the first region that is in the set $\textit{s}$, which is the smallest common region. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the region list $\textit{regions}$. @@ -84,19 +88,20 @@ class Solution: def findSmallestRegion( self, regions: List[List[str]], region1: str, region2: str ) -> str: - m = {} - for region in regions: - for r in region[1:]: - m[r] = region[0] + g = {} + for r in regions: + x = r[0] + for y in r[1:]: + g[y] = x s = set() - while m.get(region1): - s.add(region1) - region1 = m[region1] - while m.get(region2): - if region2 in s: - return region2 - region2 = m[region2] - return region1 + x = region1 + while x in g: + s.add(x) + x = g[x] + x = region2 + while x in g and x not in s: + x = g[x] + return x ``` #### Java @@ -104,24 +109,22 @@ class Solution: ```java class Solution { public String findSmallestRegion(List> regions, String region1, String region2) { - Map m = new HashMap<>(); - for (List region : regions) { - for (int i = 1; i < region.size(); ++i) { - m.put(region.get(i), region.get(0)); + Map g = new HashMap<>(); + for (var r : regions) { + String x = r.get(0); + for (String y : r.subList(1, r.size())) { + g.put(y, x); } } Set s = new HashSet<>(); - while (m.containsKey(region1)) { - s.add(region1); - region1 = m.get(region1); + for (String x = region1; x != null; x = g.get(x)) { + s.add(x); } - while (m.containsKey(region2)) { - if (s.contains(region2)) { - return region2; - } - region2 = m.get(region2); + String x = region2; + while (g.get(x) != null && !s.contains(x)) { + x = g.get(x); } - return region1; + return x; } } ``` @@ -132,20 +135,22 @@ class Solution { class Solution { public: string findSmallestRegion(vector>& regions, string region1, string region2) { - unordered_map m; - for (auto& region : regions) - for (int i = 1; i < region.size(); ++i) - m[region[i]] = region[0]; + unordered_map g; + for (const auto& r : regions) { + string x = r[0]; + for (size_t i = 1; i < r.size(); ++i) { + g[r[i]] = x; + } + } unordered_set s; - while (m.count(region1)) { - s.insert(region1); - region1 = m[region1]; + for (string x = region1; !x.empty(); x = g[x]) { + s.insert(x); } - while (m.count(region2)) { - if (s.count(region2)) return region2; - region2 = m[region2]; + string x = region2; + while (!g[x].empty() && s.find(x) == s.end()) { + x = g[x]; } - return region1; + return x; } }; ``` @@ -154,24 +159,89 @@ public: ```go func findSmallestRegion(regions [][]string, region1 string, region2 string) string { - m := make(map[string]string) - for _, region := range regions { - for i := 1; i < len(region); i++ { - m[region[i]] = region[0] + g := make(map[string]string) + + for _, r := range regions { + x := r[0] + for _, y := range r[1:] { + g[y] = x } } + s := make(map[string]bool) - for region1 != "" { - s[region1] = true - region1 = m[region1] + for x := region1; x != ""; x = g[x] { + s[x] = true } - for region2 != "" { - if s[region2] { - return region2 - } - region2 = m[region2] + + x := region2 + for g[x] != "" && !s[x] { + x = g[x] } - return region1 + + return x +} +``` + +#### TypeScript + +```ts +function findSmallestRegion(regions: string[][], region1: string, region2: string): string { + const g: Record = {}; + + for (const r of regions) { + const x = r[0]; + for (const y of r.slice(1)) { + g[y] = x; + } + } + + const s: Set = new Set(); + for (let x: string = region1; x !== undefined; x = g[x]) { + s.add(x); + } + + let x: string = region2; + while (g[x] !== undefined && !s.has(x)) { + x = g[x]; + } + + return x; +} +``` + +#### Rust + +```rust +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn find_smallest_region(regions: Vec>, region1: String, region2: String) -> String { + let mut g: HashMap = HashMap::new(); + + for r in ®ions { + let x = &r[0]; + for y in &r[1..] { + g.insert(y.clone(), x.clone()); + } + } + + let mut s: HashSet = HashSet::new(); + let mut x = Some(region1); + while let Some(region) = x { + s.insert(region.clone()); + x = g.get(®ion).cloned(); + } + + let mut x = Some(region2); + while let Some(region) = x { + if s.contains(®ion) { + return region; + } + x = g.get(®ion).cloned(); + } + + String::new() + } } ``` diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.cpp b/solution/1200-1299/1257.Smallest Common Region/Solution.cpp index 594fdfe20fa72..5ed2366943888 100644 --- a/solution/1200-1299/1257.Smallest Common Region/Solution.cpp +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.cpp @@ -1,19 +1,21 @@ class Solution { public: string findSmallestRegion(vector>& regions, string region1, string region2) { - unordered_map m; - for (auto& region : regions) - for (int i = 1; i < region.size(); ++i) - m[region[i]] = region[0]; + unordered_map g; + for (const auto& r : regions) { + string x = r[0]; + for (size_t i = 1; i < r.size(); ++i) { + g[r[i]] = x; + } + } unordered_set s; - while (m.count(region1)) { - s.insert(region1); - region1 = m[region1]; + for (string x = region1; !x.empty(); x = g[x]) { + s.insert(x); } - while (m.count(region2)) { - if (s.count(region2)) return region2; - region2 = m[region2]; + string x = region2; + while (!g[x].empty() && s.find(x) == s.end()) { + x = g[x]; } - return region1; + return x; } -}; \ No newline at end of file +}; diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.go b/solution/1200-1299/1257.Smallest Common Region/Solution.go index 9ca1c973c2ec5..93bf805571fe3 100644 --- a/solution/1200-1299/1257.Smallest Common Region/Solution.go +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.go @@ -1,20 +1,22 @@ func findSmallestRegion(regions [][]string, region1 string, region2 string) string { - m := make(map[string]string) - for _, region := range regions { - for i := 1; i < len(region); i++ { - m[region[i]] = region[0] + g := make(map[string]string) + + for _, r := range regions { + x := r[0] + for _, y := range r[1:] { + g[y] = x } } + s := make(map[string]bool) - for region1 != "" { - s[region1] = true - region1 = m[region1] + for x := region1; x != ""; x = g[x] { + s[x] = true } - for region2 != "" { - if s[region2] { - return region2 - } - region2 = m[region2] + + x := region2 + for g[x] != "" && !s[x] { + x = g[x] } - return region1 -} \ No newline at end of file + + return x +} diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.java b/solution/1200-1299/1257.Smallest Common Region/Solution.java index 348d69c373645..4739fd3f8dfa6 100644 --- a/solution/1200-1299/1257.Smallest Common Region/Solution.java +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.java @@ -1,22 +1,20 @@ class Solution { public String findSmallestRegion(List> regions, String region1, String region2) { - Map m = new HashMap<>(); - for (List region : regions) { - for (int i = 1; i < region.size(); ++i) { - m.put(region.get(i), region.get(0)); + Map g = new HashMap<>(); + for (var r : regions) { + String x = r.get(0); + for (String y : r.subList(1, r.size())) { + g.put(y, x); } } Set s = new HashSet<>(); - while (m.containsKey(region1)) { - s.add(region1); - region1 = m.get(region1); + for (String x = region1; x != null; x = g.get(x)) { + s.add(x); } - while (m.containsKey(region2)) { - if (s.contains(region2)) { - return region2; - } - region2 = m.get(region2); + String x = region2; + while (g.get(x) != null && !s.contains(x)) { + x = g.get(x); } - return region1; + return x; } -} \ No newline at end of file +} diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.py b/solution/1200-1299/1257.Smallest Common Region/Solution.py index 21507e9c6d2f4..6e18ba9118572 100644 --- a/solution/1200-1299/1257.Smallest Common Region/Solution.py +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.py @@ -2,16 +2,17 @@ class Solution: def findSmallestRegion( self, regions: List[List[str]], region1: str, region2: str ) -> str: - m = {} - for region in regions: - for r in region[1:]: - m[r] = region[0] + g = {} + for r in regions: + x = r[0] + for y in r[1:]: + g[y] = x s = set() - while m.get(region1): - s.add(region1) - region1 = m[region1] - while m.get(region2): - if region2 in s: - return region2 - region2 = m[region2] - return region1 + x = region1 + while x in g: + s.add(x) + x = g[x] + x = region2 + while x in g and x not in s: + x = g[x] + return x diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.rs b/solution/1200-1299/1257.Smallest Common Region/Solution.rs new file mode 100644 index 0000000000000..489f14fd7ea76 --- /dev/null +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.rs @@ -0,0 +1,35 @@ +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn find_smallest_region( + regions: Vec>, + region1: String, + region2: String, + ) -> String { + let mut g: HashMap = HashMap::new(); + + for r in ®ions { + let x = &r[0]; + for y in &r[1..] { + g.insert(y.clone(), x.clone()); + } + } + + let mut s: HashSet = HashSet::new(); + let mut x = Some(region1); + while let Some(region) = x { + s.insert(region.clone()); + x = g.get(®ion).cloned(); + } + + let mut x = Some(region2); + while let Some(region) = x { + if s.contains(®ion) { + return region; + } + x = g.get(®ion).cloned(); + } + + String::new() + } +} diff --git a/solution/1200-1299/1257.Smallest Common Region/Solution.ts b/solution/1200-1299/1257.Smallest Common Region/Solution.ts new file mode 100644 index 0000000000000..577f377742c13 --- /dev/null +++ b/solution/1200-1299/1257.Smallest Common Region/Solution.ts @@ -0,0 +1,22 @@ +function findSmallestRegion(regions: string[][], region1: string, region2: string): string { + const g: Record = {}; + + for (const r of regions) { + const x = r[0]; + for (const y of r.slice(1)) { + g[y] = x; + } + } + + const s: Set = new Set(); + for (let x: string = region1; x !== undefined; x = g[x]) { + s.add(x); + } + + let x: string = region2; + while (g[x] !== undefined && !s.has(x)) { + x = g[x]; + } + + return x; +}