Array
Breadth-First Search
Depth-First Search
Hash Table
String
Tree
Description
You are given some lists of regions
where the first region of each list includes all other regions in that list.
Naturally, if a region x
contains another region y
then x
is bigger than y
. Also, by definition, a region x
contains itself.
Given two regions: region1
and region2
, return the smallest region that contains both of them .
If you are given regions r1
, r2
, and r3
such that r1
includes r3
, it is guaranteed there is no r2
such that r2
includes r3
.
It is guaranteed the smallest region exists.
Example 1:
Input:
regions = [["Earth","North America","South America"],
["North America","United States","Canada"],
["United States","New York","Boston"],
["Canada","Ontario","Quebec"],
["South America","Brazil"]],
region1 = "Quebec",
region2 = "New York"
Output: "North America"
Example 2:
Input: regions = [["Earth", "North America", "South America"],["North America", "United States", "Canada"],["United States", "New York", "Boston"],["Canada", "Ontario", "Quebec"],["South America", "Brazil"]], region1 = "Canada", region2 = "South America"
Output: "Earth"
Constraints:
2 <= regions.length <= 104
2 <= regions[i].length <= 20
1 <= regions[i][j].length, region1.length, region2.length <= 20
region1 != region2
regions[i][j]
, region1
, and region2
consist of English letters.
The input is generated such that there exists a region which contains all the other regions, either directly or indirectly.
Solutions
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}\) .
Python3 Java C++ Go TypeScript Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 class Solution :
def findSmallestRegion (
self , regions : List [ List [ str ]], region1 : str , region2 : str
) -> str :
g = {}
for r in regions :
x = r [ 0 ]
for y in r [ 1 :]:
g [ y ] = x
s = set ()
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 class Solution {
public String findSmallestRegion ( List < List < String >> regions , String region1 , String region2 ) {
Map < String , String > 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 < String > s = new HashSet <> ();
for ( String x = region1 ; x != null ; x = g . get ( x )) {
s . add ( x );
}
String x = region2 ;
while ( g . get ( x ) != null && ! s . contains ( x )) {
x = g . get ( x );
}
return x ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Solution {
public :
string findSmallestRegion ( vector < vector < string >>& regions , string region1 , string region2 ) {
unordered_map < string , string > 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 < string > s ;
for ( string x = region1 ; ! x . empty (); x = g [ x ]) {
s . insert ( x );
}
string x = region2 ;
while ( ! g [ x ]. empty () && s . find ( x ) == s . end ()) {
x = g [ x ];
}
return x ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 func findSmallestRegion ( regions [][] string , region1 string , region2 string ) string {
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 x := region1 ; x != "" ; x = g [ x ] {
s [ x ] = true
}
x := region2
for g [ x ] != "" && ! s [ x ] {
x = g [ x ]
}
return x
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 function findSmallestRegion ( regions : string [][], region1 : string , region2 : string ) : string {
const g : Record < string , string > = {};
for ( const r of regions ) {
const x = r [ 0 ];
for ( const y of r . slice ( 1 )) {
g [ y ] = x ;
}
}
const s : Set < string > = 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 ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 use std :: collections ::{ HashMap , HashSet };
impl Solution {
pub fn find_smallest_region ( regions : Vec < Vec < String >> , region1 : String , region2 : String ) -> String {
let mut g : HashMap < String , String > = HashMap :: new ();
for r in & regions {
let x = & r [ 0 ];
for y in & r [ 1 .. ] {
g . insert ( y . clone (), x . clone ());
}
}
let mut s : HashSet < String > = HashSet :: new ();
let mut x = Some ( region1 );
while let Some ( region ) = x {
s . insert ( region . clone ());
x = g . get ( & region ). cloned ();
}
let mut x = Some ( region2 );
while let Some ( region ) = x {
if s . contains ( & region ) {
return region ;
}
x = g . get ( & region ). cloned ();
}
String :: new ()
}
}
GitHub