diff --git a/solution/1900-1999/1903.Largest Odd Number in String/README.md b/solution/1900-1999/1903.Largest Odd Number in String/README.md index 645a8fe4e4c8b..ddc7567d2cb0b 100644 --- a/solution/1900-1999/1903.Largest Odd Number in String/README.md +++ b/solution/1900-1999/1903.Largest Odd Number in String/README.md @@ -49,7 +49,11 @@ -从后往前遍历字符串中的每个数字,遇到奇数则直接返回结果。若遍历结束仍未遇到奇数,返回空字符串。 +**方法一:逆序遍历** + +我们可以从后往前遍历字符串,找到第一个奇数,然后返回从开头到该奇数的子字符串即可。如果不存在奇数,则返回空字符串。 + +时间复杂度 $O(n)$,其中 $n$ 是字符串 $num$ 的长度。忽略答案字符串的空间消耗,空间复杂度 $O(1)$。 @@ -84,24 +88,6 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {string} num - * @return {string} - */ -var largestOddNumber = function (num) { - let n = num.length; - for (let j = n - 1; j >= 0; j--) { - if (num.charAt(j) & (1 == 1)) { - return num.slice(0, j + 1); - } - } - return ''; -}; -``` - ### **C++** ```cpp @@ -133,6 +119,36 @@ func largestOddNumber(num string) string { } ``` +### **TypeScript** + +```ts +function largestOddNumber(num: string): string { + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); + } + } + return ''; +} +``` + +### **JavaScript** + +```js +/** + * @param {string} num + * @return {string} + */ +var largestOddNumber = function (num) { + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); + } + } + return ''; +}; +``` + ### **...** ``` diff --git a/solution/1900-1999/1903.Largest Odd Number in String/README_EN.md b/solution/1900-1999/1903.Largest Odd Number in String/README_EN.md index cd5b23ceccf04..37f0e4c9123ec 100644 --- a/solution/1900-1999/1903.Largest Odd Number in String/README_EN.md +++ b/solution/1900-1999/1903.Largest Odd Number in String/README_EN.md @@ -43,6 +43,12 @@ ## Solutions +**Solution 1: Reverse Traversal** + +We can traverse the string from the end to the beginning, find the first odd number, and then return the substring from the beginning to this odd number. If there is no odd number, return an empty string. + +The time complexity is $O(n)$, where $n$ is the length of the string $num$. Ignoring the space consumption of the answer string, the space complexity is $O(1)$. + ### **Python3** @@ -72,24 +78,6 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {string} num - * @return {string} - */ -var largestOddNumber = function (num) { - let n = num.length; - for (let j = n - 1; j >= 0; j--) { - if (num.charAt(j) & (1 == 1)) { - return num.slice(0, j + 1); - } - } - return ''; -}; -``` - ### **C++** ```cpp @@ -121,6 +109,36 @@ func largestOddNumber(num string) string { } ``` +### **TypeScript** + +```ts +function largestOddNumber(num: string): string { + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); + } + } + return ''; +} +``` + +### **JavaScript** + +```js +/** + * @param {string} num + * @return {string} + */ +var largestOddNumber = function (num) { + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); + } + } + return ''; +}; +``` + ### **...** ``` diff --git a/solution/1900-1999/1903.Largest Odd Number in String/Solution.js b/solution/1900-1999/1903.Largest Odd Number in String/Solution.js index fd8d2306a2ab7..4ae00400b2d32 100644 --- a/solution/1900-1999/1903.Largest Odd Number in String/Solution.js +++ b/solution/1900-1999/1903.Largest Odd Number in String/Solution.js @@ -3,10 +3,9 @@ * @return {string} */ var largestOddNumber = function (num) { - let n = num.length; - for (let j = n - 1; j >= 0; j--) { - if (num.charAt(j) & (1 == 1)) { - return num.slice(0, j + 1); + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); } } return ''; diff --git a/solution/1900-1999/1903.Largest Odd Number in String/Solution.ts b/solution/1900-1999/1903.Largest Odd Number in String/Solution.ts new file mode 100644 index 0000000000000..4480fe7ec78a6 --- /dev/null +++ b/solution/1900-1999/1903.Largest Odd Number in String/Solution.ts @@ -0,0 +1,8 @@ +function largestOddNumber(num: string): string { + for (let i = num.length - 1; ~i; --i) { + if (Number(num[i]) & 1) { + return num.slice(0, i + 1); + } + } + return ''; +} diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README.md b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README.md index 59f2eae5302d9..7623a31b09997 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README.md +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README.md @@ -62,7 +62,13 @@ -转换为“分钟”进行计算。 +**方法一:转换为分钟数** + +我们可以将输入的字符串转换为分钟数 $a$ 和 $b$,如果 $a > b$,则说明跨越了午夜,需要将 $b$ 加上一天的分钟数 $1440$。 + +然后我们将 $a$ 向上取整到 $15$ 的倍数,将 $b$ 向下取整到 $15$ 的倍数,最后返回 $b$ 与 $a$ 的差值即可,注意要取 $0$ 和 $b - a$ 中的较大值。 + +时间复杂度 $O(1)$,空间复杂度 $O(1)$。 @@ -72,15 +78,15 @@ ```python class Solution: - def numberOfRounds(self, startTime: str, finishTime: str) -> int: - def get(s: str) -> int: + def numberOfRounds(self, loginTime: str, logoutTime: str) -> int: + def f(s: str) -> int: return int(s[:2]) * 60 + int(s[3:]) - start, finish = get(startTime), get(finishTime) - if start > finish: - finish += 24 * 60 - start, finish = (start + 14) // 15, finish // 15 - return max(0, finish - start) + a, b = f(loginTime), f(logoutTime) + if a > b: + b += 1440 + a, b = (a + 14) // 15, b // 15 + return max(0, b - a) ``` ### **Java** @@ -89,38 +95,19 @@ class Solution: ```java class Solution { - public int numberOfRounds(String startTime, String finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; + public int numberOfRounds(String loginTime, String logoutTime) { + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; } - start = (start + 14) / 15; - finish /= 15; - return Math.max(0, finish - start); + return Math.max(0, b / 15 - (a + 14) / 15); } - private int get(String s) { - return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3)); - } -} -``` - -### **TypeScript** - -```ts -function numberOfRounds(startTime: string, finishTime: string): number { - let m1 = toMinutes(startTime), - m2 = toMinutes(finishTime); - if (m1 > m2) { - m2 += 24 * 60; + private int f(String s) { + int h = Integer.parseInt(s.substring(0, 2)); + int m = Integer.parseInt(s.substring(3, 5)); + return h * 60 + m; } - let ans = Math.floor(m2 / 15) - Math.ceil(m1 / 15); - return ans > 0 ? ans : 0; -} - -function toMinutes(time: string): number { - let [h, m] = time.split(':').map(Number); - return h * 60 + m; } ``` @@ -129,21 +116,17 @@ function toMinutes(time: string): number { ```cpp class Solution { public: - int numberOfRounds(string startTime, string finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; + int numberOfRounds(string loginTime, string logoutTime) { + auto f = [](string& s) { + int h, m; + sscanf(s.c_str(), "%d:%d", &h, &m); + return h * 60 + m; + }; + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; } - start = (start + 14) / 15; - finish /= 15; - return max(0, finish - start); - } - -private: - int get(string s) { - int a, b; - sscanf(s.c_str(), "%d:%d", &a, &b); - return a * 60 + b; + return max(0, b / 15 - (a + 14) / 15); } }; ``` @@ -151,24 +134,33 @@ private: ### **Go** ```go -func numberOfRounds(startTime string, finishTime string) int { - start, finish := get(startTime), get(finishTime) - if start > finish { - finish += 24 * 60 +func numberOfRounds(loginTime string, logoutTime string) int { + f := func(s string) int { + var h, m int + fmt.Sscanf(s, "%d:%d", &h, &m) + return h*60 + m } - start = (start + 14) / 15 - finish /= 15 - if start > finish { - return 0 + a, b := f(loginTime), f(logoutTime) + if a > b { + b += 1440 } - return finish - start - + return max(0, b/15-(a+14)/15) } +``` -func get(s string) int { - var a, b int - fmt.Sscanf(s, "%d:%d", &a, &b) - return a*60 + b +### **TypeScript** + +```ts +function numberOfRounds(startTime: string, finishTime: string): number { + const f = (s: string): number => { + const [h, m] = s.split(':').map(Number); + return h * 60 + m; + }; + let [a, b] = [f(startTime), f(finishTime)]; + if (a > b) { + b += 1440; + } + return Math.max(0, Math.floor(b / 15) - Math.ceil(a / 15)); } ``` diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README_EN.md b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README_EN.md index 405bd9c2736d7..84e24f5c9aaf5 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README_EN.md +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/README_EN.md @@ -55,82 +55,67 @@ You did not play the full round from 10:00 to 10:15 because you logged out at 10 ## Solutions +**Solution 1: Convert to Minutes** + +We can convert the input strings to minutes $a$ and $b$. If $a > b$, it means that it crosses midnight, so we need to add one day's minutes $1440$ to $b$. + +Then we round $a$ up to the nearest multiple of $15$, and round $b$ down to the nearest multiple of $15$. Finally, we return the difference between $b$ and $a$. Note that we should take the larger value between $0$ and $b - a$. + +The time complexity is $O(1)$, and the space complexity is $O(1)$. + ### **Python3** ```python class Solution: - def numberOfRounds(self, startTime: str, finishTime: str) -> int: - def get(s: str) -> int: + def numberOfRounds(self, loginTime: str, logoutTime: str) -> int: + def f(s: str) -> int: return int(s[:2]) * 60 + int(s[3:]) - start, finish = get(startTime), get(finishTime) - if start > finish: - finish += 24 * 60 - start, finish = (start + 14) // 15, finish // 15 - return max(0, finish - start) + a, b = f(loginTime), f(logoutTime) + if a > b: + b += 1440 + a, b = (a + 14) // 15, b // 15 + return max(0, b - a) ``` ### **Java** ```java class Solution { - public int numberOfRounds(String startTime, String finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; + public int numberOfRounds(String loginTime, String logoutTime) { + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; } - start = (start + 14) / 15; - finish /= 15; - return Math.max(0, finish - start); + return Math.max(0, b / 15 - (a + 14) / 15); } - private int get(String s) { - return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3)); + private int f(String s) { + int h = Integer.parseInt(s.substring(0, 2)); + int m = Integer.parseInt(s.substring(3, 5)); + return h * 60 + m; } } ``` -### **TypeScript** - -```ts -function numberOfRounds(startTime: string, finishTime: string): number { - let m1 = toMinutes(startTime), - m2 = toMinutes(finishTime); - if (m1 > m2) { - m2 += 24 * 60; - } - let ans = Math.floor(m2 / 15) - Math.ceil(m1 / 15); - return ans > 0 ? ans : 0; -} - -function toMinutes(time: string): number { - let [h, m] = time.split(':').map(Number); - return h * 60 + m; -} -``` - ### **C++** ```cpp class Solution { public: - int numberOfRounds(string startTime, string finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; + int numberOfRounds(string loginTime, string logoutTime) { + auto f = [](string& s) { + int h, m; + sscanf(s.c_str(), "%d:%d", &h, &m); + return h * 60 + m; + }; + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; } - start = (start + 14) / 15; - finish /= 15; - return max(0, finish - start); - } - -private: - int get(string s) { - int a, b; - sscanf(s.c_str(), "%d:%d", &a, &b); - return a * 60 + b; + return max(0, b / 15 - (a + 14) / 15); } }; ``` @@ -138,24 +123,33 @@ private: ### **Go** ```go -func numberOfRounds(startTime string, finishTime string) int { - start, finish := get(startTime), get(finishTime) - if start > finish { - finish += 24 * 60 +func numberOfRounds(loginTime string, logoutTime string) int { + f := func(s string) int { + var h, m int + fmt.Sscanf(s, "%d:%d", &h, &m) + return h*60 + m } - start = (start + 14) / 15 - finish /= 15 - if start > finish { - return 0 + a, b := f(loginTime), f(logoutTime) + if a > b { + b += 1440 } - return finish - start - + return max(0, b/15-(a+14)/15) } +``` -func get(s string) int { - var a, b int - fmt.Sscanf(s, "%d:%d", &a, &b) - return a*60 + b +### **TypeScript** + +```ts +function numberOfRounds(startTime: string, finishTime: string): number { + const f = (s: string): number => { + const [h, m] = s.split(':').map(Number); + return h * 60 + m; + }; + let [a, b] = [f(startTime), f(finishTime)]; + if (a > b) { + b += 1440; + } + return Math.max(0, Math.floor(b / 15) - Math.ceil(a / 15)); } ``` diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.cpp b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.cpp index c68792c2ee9c3..cd138fa92911b 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.cpp +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.cpp @@ -1,19 +1,15 @@ -class Solution { -public: - int numberOfRounds(string startTime, string finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; - } - start = (start + 14) / 15; - finish /= 15; - return max(0, finish - start); - } - -private: - int get(string s) { - int a, b; - sscanf(s.c_str(), "%d:%d", &a, &b); - return a * 60 + b; - } +class Solution { +public: + int numberOfRounds(string loginTime, string logoutTime) { + auto f = [](string& s) { + int h, m; + sscanf(s.c_str(), "%d:%d", &h, &m); + return h * 60 + m; + }; + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; + } + return max(0, b / 15 - (a + 14) / 15); + } }; \ No newline at end of file diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.go b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.go index 2639f2663cf51..ca6022c651ca2 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.go +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.go @@ -1,19 +1,12 @@ -func numberOfRounds(startTime string, finishTime string) int { - start, finish := get(startTime), get(finishTime) - if start > finish { - finish += 24 * 60 +func numberOfRounds(loginTime string, logoutTime string) int { + f := func(s string) int { + var h, m int + fmt.Sscanf(s, "%d:%d", &h, &m) + return h*60 + m } - start = (start + 14) / 15 - finish /= 15 - if start > finish { - return 0 + a, b := f(loginTime), f(logoutTime) + if a > b { + b += 1440 } - return finish - start - -} - -func get(s string) int { - var a, b int - fmt.Sscanf(s, "%d:%d", &a, &b) - return a*60 + b + return max(0, b/15-(a+14)/15) } \ No newline at end of file diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.java b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.java index 4ca99cb0968d6..7fa77e82cb30a 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.java +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.java @@ -1,15 +1,15 @@ -class Solution { - public int numberOfRounds(String startTime, String finishTime) { - int start = get(startTime), finish = get(finishTime); - if (start > finish) { - finish += 24 * 60; - } - start = (start + 14) / 15; - finish /= 15; - return Math.max(0, finish - start); - } - - private int get(String s) { - return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3)); - } +class Solution { + public int numberOfRounds(String loginTime, String logoutTime) { + int a = f(loginTime), b = f(logoutTime); + if (a > b) { + b += 1440; + } + return Math.max(0, b / 15 - (a + 14) / 15); + } + + private int f(String s) { + int h = Integer.parseInt(s.substring(0, 2)); + int m = Integer.parseInt(s.substring(3, 5)); + return h * 60 + m; + } } \ No newline at end of file diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.py b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.py index 6aa97913dd2ee..c95b4b987d3c5 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.py +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.py @@ -1,10 +1,10 @@ -class Solution: - def numberOfRounds(self, startTime: str, finishTime: str) -> int: - def get(s: str) -> int: - return int(s[:2]) * 60 + int(s[3:]) - - start, finish = get(startTime), get(finishTime) - if start > finish: - finish += 24 * 60 - start, finish = (start + 14) // 15, finish // 15 - return max(0, finish - start) +class Solution: + def numberOfRounds(self, loginTime: str, logoutTime: str) -> int: + def f(s: str) -> int: + return int(s[:2]) * 60 + int(s[3:]) + + a, b = f(loginTime), f(logoutTime) + if a > b: + b += 1440 + a, b = (a + 14) // 15, b // 15 + return max(0, b - a) diff --git a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.ts b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.ts index 276ba5cd4fbfc..11ede4dc426e7 100644 --- a/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.ts +++ b/solution/1900-1999/1904.The Number of Full Rounds You Have Played/Solution.ts @@ -1,14 +1,11 @@ function numberOfRounds(startTime: string, finishTime: string): number { - let m1 = toMinutes(startTime), - m2 = toMinutes(finishTime); - if (m1 > m2) { - m2 += 24 * 60; + const f = (s: string): number => { + const [h, m] = s.split(':').map(Number); + return h * 60 + m; + }; + let [a, b] = [f(startTime), f(finishTime)]; + if (a > b) { + b += 1440; } - let ans = Math.floor(m2 / 15) - Math.ceil(m1 / 15); - return ans > 0 ? ans : 0; -} - -function toMinutes(time: string): number { - let [h, m] = time.split(':').map(Number); - return h * 60 + m; + return Math.max(0, Math.floor(b / 15) - Math.ceil(a / 15)); } diff --git a/solution/1900-1999/1905.Count Sub Islands/README.md b/solution/1900-1999/1905.Count Sub Islands/README.md index eb2fb018bdee0..17c3d49b63237 100644 --- a/solution/1900-1999/1905.Count Sub Islands/README.md +++ b/solution/1900-1999/1905.Count Sub Islands/README.md @@ -45,7 +45,11 @@ grid2 中标红的 1 区域是子岛屿,总共有 2 个子岛屿。 -BFS、DFS 或者并查集。 +**方法一:DFS** + +我们可以遍历矩阵 `grid2` 中的每一个格子 $(i, j)$,如果该格子为 $1$,则从该格子开始进行深度优先搜索,将与该格子相连的所有格子的值都置为 $0$,并记录与该格子相连的所有格子中,`grid1` 中对应格子的值是否为 $1$,如果为 $1$,则说明该格子在 `grid1` 中也是一个岛屿,否则不是。最后统计 `grid2` 中子岛屿的数量即可。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵 `grid1` 和 `grid2` 的行数和列数。 @@ -53,333 +57,113 @@ BFS、DFS 或者并查集。 -BFS - Flood Fill 算法: - ```python class Solution: def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def bfs(i, j): - q = deque([(i, j)]) + def dfs(i: int, j: int) -> int: + ok = grid1[i][j] grid2[i][j] = 0 - ans = True - while q: - i, j = q.popleft() - if grid1[i][j] == 0: - ans = False - for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and grid2[x][y]: - q.append((x, y)) - grid2[x][y] = 0 - return ans - - m, n = len(grid1), len(grid1[0]) - return sum(grid2[i][j] and bfs(i, j) for i in range(m) for j in range(n)) -``` - -DFS: - -```python -class Solution: - def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def dfs(i, j): - ans = grid1[i][j] == 1 - grid2[i][j] = 0 - for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]: + for a, b in pairwise(dirs): x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and grid2[x][y] == 1 and not dfs(x, y): - ans = False - return ans + if 0 <= x < m and 0 <= y < n and grid2[x][y] and not dfs(x, y): + ok = 0 + return ok m, n = len(grid1), len(grid1[0]) - return sum(grid2[i][j] == 1 and dfs(i, j) for i in range(m) for j in range(n)) + dirs = (-1, 0, 1, 0, -1) + return sum(dfs(i, j) for i in range(m) for j in range(n) if grid2[i][j]) ``` -并查集: - ```python class Solution: def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def find(x): - if p[x] != x: - p[x] = find(p[x]) - return p[x] + def bfs(i: int, j: int) -> int: + ok = grid1[i][j] + q = deque([(i, j)]) + grid2[i][j] = 0 + while q: + i, j = q.popleft() + for a, b in pairwise(dirs): + x, y = i + a, j + b + if 0 <= x < m and 0 <= y < n and grid2[x][y]: + q.append((x, y)) + ok = ok & grid1[x][y] + grid2[x][y] = 0 + return ok m, n = len(grid1), len(grid1[0]) - p = list(range(m * n)) - for i in range(m): - for j in range(n): - if grid2[i][j]: - for a, b in [[0, 1], [1, 0]]: - x, y = i + a, j + b - if x < m and y < n and grid2[x][y]: - p[find(x * n + y)] = find(i * n + j) - s = [0] * (m * n) - for i in range(m): - for j in range(n): - if grid2[i][j]: - s[find(i * n + j)] = 1 - for i in range(m): - for j in range(n): - root = find(i * n + j) - if s[root] and grid1[i][j] == 0: - s[root] = 0 - return sum(s) + dirs = (-1, 0, 1, 0, -1) + return sum(bfs(i, j) for i in range(m) for j in range(n) if grid2[i][j]) ``` ### **Java** -BFS - Flood Fill 算法: - ```java class Solution { - public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; - int ans = 0; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && bfs(i, j, m, n, grid1, grid2)) { - ++ans; - } - } - } - return ans; - } - - private boolean bfs(int i, int j, int m, int n, int[][] grid1, int[][] grid2) { - Queue q = new ArrayDeque<>(); - grid2[i][j] = 0; - q.offer(new int[] {i, j}); - boolean ans = true; - int[] dirs = {-1, 0, 1, 0, -1}; - while (!q.isEmpty()) { - int[] p = q.poll(); - i = p[0]; - j = p[1]; - if (grid1[i][j] == 0) { - ans = false; - } - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1) { - q.offer(new int[] {x, y}); - grid2[x][y] = 0; - } - } - } - return ans; - } -} -``` - -DFS: + private final int[] dirs = {-1, 0, 1, 0, -1}; + private int[][] grid1; + private int[][] grid2; + private int m; + private int n; -```java -class Solution { public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; + m = grid1.length; + n = grid1[0].length; + this.grid1 = grid1; + this.grid2 = grid2; int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) { - ++ans; + if (grid2[i][j] == 1) { + ans += dfs(i, j); } } } return ans; } - private boolean dfs(int i, int j, int m, int n, int[][] grid1, int[][] grid2) { - boolean ans = grid1[i][j] == 1; + private int dfs(int i, int j) { + int ok = grid1[i][j]; grid2[i][j] = 0; - int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 - && !dfs(x, y, m, n, grid1, grid2)) { - ans = false; - } - } - return ans; - } -} -``` - -并查集: - -```java -class Solution { - private int[] p; - - public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; - p = new int[m * n]; - for (int i = 0; i < p.length; ++i) { - p[i] = i; - } - int[] dirs = {1, 0, 1}; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1) { - for (int k = 0; k < 2; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x < m && y < n && grid2[x][y] == 1) { - p[find(x * n + y)] = find(i * n + j); - } - } - } - } - } - int[] s = new int[m * n]; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1) { - s[find(i * n + j)] = 1; - } - } - } - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - int root = find(i * n + j); - if (s[root] == 1 && grid1[i][j] == 0) { - s[root] = 0; - } - } - } - int ans = 0; - for (int i = 0; i < s.length; ++i) { - ans += s[i]; - } - return ans; - } - - private int find(int x) { - if (p[x] != x) { - p[x] = find(p[x]); - } - return p[x]; - } -} -``` - -### **TypeScript** - -```ts -function countSubIslands(grid1: number[][], grid2: number[][]): number { - let m = grid1.length, - n = grid1[0].length; - let ans = 0; - for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(grid1, grid2, i, j)) { - ++ans; + int x = i + dirs[k], y = j + dirs[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1) { + ok &= dfs(x, y); } } + return ok; } - return ans; -} - -function dfs(grid1: number[][], grid2: number[][], i: number, j: number): boolean { - let m = grid1.length, - n = grid1[0].length; - let ans = true; - if (grid1[i][j] == 0) { - ans = false; - } - grid2[i][j] = 0; - for (let [dx, dy] of [ - [0, 1], - [0, -1], - [1, 0], - [-1, 0], - ]) { - let x = i + dx, - y = j + dy; - if (x < 0 || x > m - 1 || y < 0 || y > n - 1 || grid2[x][y] == 0) { - continue; - } - if (!dfs(grid1, grid2, x, y)) { - ans = false; - } - } - return ans; } ``` ### **C++** -BFS - Flood Fill 算法: - ```cpp class Solution { public: int countSubIslands(vector>& grid1, vector>& grid2) { - int m = grid1.size(); - int n = grid1[0].size(); + int m = grid1.size(), n = grid1[0].size(); int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - ans += (grid2[i][j] == 1 && bfs(i, j, m, n, grid1, grid2)); - return ans; - } - - bool bfs(int i, int j, int m, int n, vector>& grid1, vector>& grid2) { - queue> q; - q.push({i, j}); - grid2[i][j] = 0; - bool ans = true; - vector dirs = {-1, 0, 1, 0, -1}; - while (!q.empty()) { - auto p = q.front(); - q.pop(); - i = p.first; - j = p.second; - if (grid1[i][j] == 0) ans = false; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + int ok = grid1[i][j]; + grid2[i][j] = 0; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { - q.push({x, y}); - grid2[x][y] = 0; + ok &= dfs(x, y); + } + } + return ok; + }; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid2[i][j]) { + ans += dfs(i, j); } } - } - return ans; - } -}; -``` - -DFS: - -```cpp -class Solution { -public: - int countSubIslands(vector>& grid1, vector>& grid2) { - int m = grid1.size(); - int n = grid1[0].size(); - int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) - ++ans; - return ans; - } - - bool dfs(int i, int j, int m, int n, vector>& grid1, vector>& grid2) { - bool ans = grid1[i][j]; - grid2[i][j] = 0; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] && !dfs(x, y, m, n, grid1, grid2)) - ans = false; } return ans; } @@ -388,71 +172,59 @@ public: ### **Go** -BFS - Flood Fill 算法: - ```go -func countSubIslands(grid1 [][]int, grid2 [][]int) int { +func countSubIslands(grid1 [][]int, grid2 [][]int) (ans int) { m, n := len(grid1), len(grid1[0]) - ans := 0 - bfs := func(i, j int) bool { - q := [][]int{{i, j}} + dirs := [5]int{-1, 0, 1, 0, -1} + var dfs func(i, j int) int + dfs = func(i, j int) int { + ok := grid1[i][j] grid2[i][j] = 0 - res := true - dirs := []int{-1, 0, 1, 0, -1} - for len(q) > 0 { - i, j = q[0][0], q[0][1] - if grid1[i][j] == 0 { - res = false - } - q = q[1:] - for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 { - q = append(q, []int{x, y}) - grid2[x][y] = 0 - } + for k := 0; k < 4; k++ { + x, y := i+dirs[k], j+dirs[k+1] + if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && dfs(x, y) == 0 { + ok = 0 } } - return res + return ok } for i := 0; i < m; i++ { for j := 0; j < n; j++ { - if grid2[i][j] == 1 && bfs(i, j) { - ans++ + if grid2[i][j] == 1 { + ans += dfs(i, j) } } } - return ans + return } ``` -DFS: +### **TypeScript** -```go -func countSubIslands(grid1 [][]int, grid2 [][]int) int { - m, n := len(grid1), len(grid1[0]) - ans := 0 - var dfs func(i, j int) bool - dfs = func(i, j int) bool { - res := grid1[i][j] == 1 - grid2[i][j] = 0 - dirs := []int{-1, 0, 1, 0, -1} - for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && !dfs(x, y) { - res = false - } - } - return res - } - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if grid2[i][j] == 1 && dfs(i, j) { - ans++ - } - } - } - return ans +```ts +function countSubIslands(grid1: number[][], grid2: number[][]): number { + const [m, n] = [grid1.length, grid1[0].length]; + let ans = 0; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): number => { + let ok = grid1[i][j]; + grid2[i][j] = 0; + for (let k = 0; k < 4; ++k) { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { + ok &= dfs(x, y); + } + } + return ok; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; j++) { + if (grid2[i][j]) { + ans += dfs(i, j); + } + } + } + return ans; } ``` diff --git a/solution/1900-1999/1905.Count Sub Islands/README_EN.md b/solution/1900-1999/1905.Count Sub Islands/README_EN.md index 9c22bec43d9a7..8a9213ae3eec5 100644 --- a/solution/1900-1999/1905.Count Sub Islands/README_EN.md +++ b/solution/1900-1999/1905.Count Sub Islands/README_EN.md @@ -41,292 +41,121 @@ The 1s colored red in grid2 are those considered to be part of a sub-island. The ## Solutions -BFS, DFS or Union find. +**Solution 1: DFS** - - -### **Python3** +We can traverse each cell $(i, j)$ in the matrix `grid2`. If the value of the cell is $1$, we start a depth-first search from this cell, set the value of all cells connected to this cell to $0$, and record whether the corresponding cell in `grid1` is also $1$ for all cells connected to this cell. If it is $1$, it means that this cell is also an island in `grid1`, otherwise it is not. Finally, we count the number of sub-islands in `grid2`. -BFS: +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the matrices `grid1` and `grid2`, respectively. -```python -class Solution: - def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def bfs(i, j): - q = deque([(i, j)]) - grid2[i][j] = 0 - ans = True - while q: - i, j = q.popleft() - if grid1[i][j] == 0: - ans = False - for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and grid2[x][y]: - q.append((x, y)) - grid2[x][y] = 0 - return ans - - m, n = len(grid1), len(grid1[0]) - return sum(grid2[i][j] and bfs(i, j) for i in range(m) for j in range(n)) -``` + -DFS: +### **Python3** ```python class Solution: def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def dfs(i, j): - ans = grid1[i][j] == 1 + def dfs(i: int, j: int) -> int: + ok = grid1[i][j] grid2[i][j] = 0 - for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]: + for a, b in pairwise(dirs): x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and grid2[x][y] == 1 and not dfs(x, y): - ans = False - return ans + if 0 <= x < m and 0 <= y < n and grid2[x][y] and not dfs(x, y): + ok = 0 + return ok m, n = len(grid1), len(grid1[0]) - return sum(grid2[i][j] == 1 and dfs(i, j) for i in range(m) for j in range(n)) + dirs = (-1, 0, 1, 0, -1) + return sum(dfs(i, j) for i in range(m) for j in range(n) if grid2[i][j]) ``` -Union find: - ```python class Solution: def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def find(x): - if p[x] != x: - p[x] = find(p[x]) - return p[x] + def bfs(i: int, j: int) -> int: + ok = grid1[i][j] + q = deque([(i, j)]) + grid2[i][j] = 0 + while q: + i, j = q.popleft() + for a, b in pairwise(dirs): + x, y = i + a, j + b + if 0 <= x < m and 0 <= y < n and grid2[x][y]: + q.append((x, y)) + ok = ok & grid1[x][y] + grid2[x][y] = 0 + return ok m, n = len(grid1), len(grid1[0]) - p = list(range(m * n)) - for i in range(m): - for j in range(n): - if grid2[i][j]: - for a, b in [[0, 1], [1, 0]]: - x, y = i + a, j + b - if x < m and y < n and grid2[x][y]: - p[find(x * n + y)] = find(i * n + j) - s = [0] * (m * n) - for i in range(m): - for j in range(n): - if grid2[i][j]: - s[find(i * n + j)] = 1 - for i in range(m): - for j in range(n): - root = find(i * n + j) - if s[root] and grid1[i][j] == 0: - s[root] = 0 - return sum(s) + dirs = (-1, 0, 1, 0, -1) + return sum(bfs(i, j) for i in range(m) for j in range(n) if grid2[i][j]) ``` ### **Java** -DFS: - ```java class Solution { + private final int[] dirs = {-1, 0, 1, 0, -1}; + private int[][] grid1; + private int[][] grid2; + private int m; + private int n; + public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; + m = grid1.length; + n = grid1[0].length; + this.grid1 = grid1; + this.grid2 = grid2; int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) { - ++ans; + if (grid2[i][j] == 1) { + ans += dfs(i, j); } } } return ans; } - private boolean dfs(int i, int j, int m, int n, int[][] grid1, int[][] grid2) { - boolean ans = grid1[i][j] == 1; + private int dfs(int i, int j) { + int ok = grid1[i][j]; grid2[i][j] = 0; - int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 - && !dfs(x, y, m, n, grid1, grid2)) { - ans = false; - } - } - return ans; - } -} -``` - -Union find: - -```java -class Solution { - private int[] p; - - public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; - p = new int[m * n]; - for (int i = 0; i < p.length; ++i) { - p[i] = i; - } - int[] dirs = {1, 0, 1}; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1) { - for (int k = 0; k < 2; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x < m && y < n && grid2[x][y] == 1) { - p[find(x * n + y)] = find(i * n + j); - } - } - } - } - } - int[] s = new int[m * n]; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1) { - s[find(i * n + j)] = 1; - } - } - } - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - int root = find(i * n + j); - if (s[root] == 1 && grid1[i][j] == 0) { - s[root] = 0; - } - } - } - int ans = 0; - for (int i = 0; i < s.length; ++i) { - ans += s[i]; - } - return ans; - } - - private int find(int x) { - if (p[x] != x) { - p[x] = find(p[x]); - } - return p[x]; - } -} -``` - -### **TypeScript** - -```ts -function countSubIslands(grid1: number[][], grid2: number[][]): number { - let m = grid1.length, - n = grid1[0].length; - let ans = 0; - for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(grid1, grid2, i, j)) { - ++ans; + int x = i + dirs[k], y = j + dirs[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1) { + ok &= dfs(x, y); } } + return ok; } - return ans; -} - -function dfs(grid1: number[][], grid2: number[][], i: number, j: number): boolean { - let m = grid1.length, - n = grid1[0].length; - let ans = true; - if (grid1[i][j] == 0) { - ans = false; - } - grid2[i][j] = 0; - for (let [dx, dy] of [ - [0, 1], - [0, -1], - [1, 0], - [-1, 0], - ]) { - let x = i + dx, - y = j + dy; - if (x < 0 || x > m - 1 || y < 0 || y > n - 1 || grid2[x][y] == 0) { - continue; - } - if (!dfs(grid1, grid2, x, y)) { - ans = false; - } - } - return ans; } ``` ### **C++** -BFS: - ```cpp class Solution { public: int countSubIslands(vector>& grid1, vector>& grid2) { - int m = grid1.size(); - int n = grid1[0].size(); + int m = grid1.size(), n = grid1[0].size(); int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - ans += (grid2[i][j] == 1 && bfs(i, j, m, n, grid1, grid2)); - return ans; - } - - bool bfs(int i, int j, int m, int n, vector>& grid1, vector>& grid2) { - queue> q; - q.push({i, j}); - grid2[i][j] = 0; - bool ans = true; - vector dirs = {-1, 0, 1, 0, -1}; - while (!q.empty()) { - auto p = q.front(); - q.pop(); - i = p.first; - j = p.second; - if (grid1[i][j] == 0) ans = false; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + int ok = grid1[i][j]; + grid2[i][j] = 0; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { - q.push({x, y}); - grid2[x][y] = 0; + ok &= dfs(x, y); + } + } + return ok; + }; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid2[i][j]) { + ans += dfs(i, j); } } - } - return ans; - } -}; -``` - -DFS: - -```cpp -class Solution { -public: - int countSubIslands(vector>& grid1, vector>& grid2) { - int m = grid1.size(); - int n = grid1[0].size(); - int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) - ++ans; - return ans; - } - - bool dfs(int i, int j, int m, int n, vector>& grid1, vector>& grid2) { - bool ans = grid1[i][j]; - grid2[i][j] = 0; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] && !dfs(x, y, m, n, grid1, grid2)) - ans = false; } return ans; } @@ -335,71 +164,59 @@ public: ### **Go** -BFS: - ```go -func countSubIslands(grid1 [][]int, grid2 [][]int) int { +func countSubIslands(grid1 [][]int, grid2 [][]int) (ans int) { m, n := len(grid1), len(grid1[0]) - ans := 0 - bfs := func(i, j int) bool { - q := [][]int{{i, j}} + dirs := [5]int{-1, 0, 1, 0, -1} + var dfs func(i, j int) int + dfs = func(i, j int) int { + ok := grid1[i][j] grid2[i][j] = 0 - res := true - dirs := []int{-1, 0, 1, 0, -1} - for len(q) > 0 { - i, j = q[0][0], q[0][1] - if grid1[i][j] == 0 { - res = false - } - q = q[1:] - for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 { - q = append(q, []int{x, y}) - grid2[x][y] = 0 - } + for k := 0; k < 4; k++ { + x, y := i+dirs[k], j+dirs[k+1] + if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && dfs(x, y) == 0 { + ok = 0 } } - return res + return ok } for i := 0; i < m; i++ { for j := 0; j < n; j++ { - if grid2[i][j] == 1 && bfs(i, j) { - ans++ + if grid2[i][j] == 1 { + ans += dfs(i, j) } } } - return ans + return } ``` -DFS: +### **TypeScript** -```go -func countSubIslands(grid1 [][]int, grid2 [][]int) int { - m, n := len(grid1), len(grid1[0]) - ans := 0 - var dfs func(i, j int) bool - dfs = func(i, j int) bool { - res := grid1[i][j] == 1 - grid2[i][j] = 0 - dirs := []int{-1, 0, 1, 0, -1} - for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && !dfs(x, y) { - res = false - } - } - return res - } - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if grid2[i][j] == 1 && dfs(i, j) { - ans++ - } - } - } - return ans +```ts +function countSubIslands(grid1: number[][], grid2: number[][]): number { + const [m, n] = [grid1.length, grid1[0].length]; + let ans = 0; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): number => { + let ok = grid1[i][j]; + grid2[i][j] = 0; + for (let k = 0; k < 4; ++k) { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { + ok &= dfs(x, y); + } + } + return ok; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; j++) { + if (grid2[i][j]) { + ans += dfs(i, j); + } + } + } + return ans; } ``` diff --git a/solution/1900-1999/1905.Count Sub Islands/Solution.cpp b/solution/1900-1999/1905.Count Sub Islands/Solution.cpp index b6bcc763de745..b32c5a6278f8e 100644 --- a/solution/1900-1999/1905.Count Sub Islands/Solution.cpp +++ b/solution/1900-1999/1905.Count Sub Islands/Solution.cpp @@ -1,25 +1,27 @@ -class Solution { -public: - int countSubIslands(vector>& grid1, vector>& grid2) { - int m = grid1.size(); - int n = grid1[0].size(); - int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) - ++ans; - return ans; - } - - bool dfs(int i, int j, int m, int n, vector>& grid1, vector>& grid2) { - bool ans = grid1[i][j]; - grid2[i][j] = 0; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] && !dfs(x, y, m, n, grid1, grid2)) - ans = false; - } - return ans; - } +class Solution { +public: + int countSubIslands(vector>& grid1, vector>& grid2) { + int m = grid1.size(), n = grid1[0].size(); + int ans = 0; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + int ok = grid1[i][j]; + grid2[i][j] = 0; + for (int k = 0; k < 4; ++k) { + int x = i + dirs[k], y = j + dirs[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { + ok &= dfs(x, y); + } + } + return ok; + }; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid2[i][j]) { + ans += dfs(i, j); + } + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1900-1999/1905.Count Sub Islands/Solution.go b/solution/1900-1999/1905.Count Sub Islands/Solution.go index 473b4d5897b11..8b61ccb279790 100644 --- a/solution/1900-1999/1905.Count Sub Islands/Solution.go +++ b/solution/1900-1999/1905.Count Sub Islands/Solution.go @@ -1,25 +1,24 @@ -func countSubIslands(grid1 [][]int, grid2 [][]int) int { +func countSubIslands(grid1 [][]int, grid2 [][]int) (ans int) { m, n := len(grid1), len(grid1[0]) - ans := 0 - var dfs func(i, j int) bool - dfs = func(i, j int) bool { - res := grid1[i][j] == 1 + dirs := [5]int{-1, 0, 1, 0, -1} + var dfs func(i, j int) int + dfs = func(i, j int) int { + ok := grid1[i][j] grid2[i][j] = 0 - dirs := []int{-1, 0, 1, 0, -1} for k := 0; k < 4; k++ { x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && !dfs(x, y) { - res = false + if x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 && dfs(x, y) == 0 { + ok = 0 } } - return res + return ok } for i := 0; i < m; i++ { for j := 0; j < n; j++ { - if grid2[i][j] == 1 && dfs(i, j) { - ans++ + if grid2[i][j] == 1 { + ans += dfs(i, j) } } } - return ans + return } \ No newline at end of file diff --git a/solution/1900-1999/1905.Count Sub Islands/Solution.java b/solution/1900-1999/1905.Count Sub Islands/Solution.java index 79d8948e310f7..350826143a009 100644 --- a/solution/1900-1999/1905.Count Sub Islands/Solution.java +++ b/solution/1900-1999/1905.Count Sub Islands/Solution.java @@ -1,30 +1,35 @@ -class Solution { - public int countSubIslands(int[][] grid1, int[][] grid2) { - int m = grid1.length; - int n = grid1[0].length; - int ans = 0; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(i, j, m, n, grid1, grid2)) { - ++ans; - } - } - } - return ans; - } - - private boolean dfs(int i, int j, int m, int n, int[][] grid1, int[][] grid2) { - boolean ans = grid1[i][j] == 1; - grid2[i][j] = 0; - int[] dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1 - && !dfs(x, y, m, n, grid1, grid2)) { - ans = false; - } - } - return ans; - } +class Solution { + private final int[] dirs = {-1, 0, 1, 0, -1}; + private int[][] grid1; + private int[][] grid2; + private int m; + private int n; + + public int countSubIslands(int[][] grid1, int[][] grid2) { + m = grid1.length; + n = grid1[0].length; + this.grid1 = grid1; + this.grid2 = grid2; + int ans = 0; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid2[i][j] == 1) { + ans += dfs(i, j); + } + } + } + return ans; + } + + private int dfs(int i, int j) { + int ok = grid1[i][j]; + grid2[i][j] = 0; + for (int k = 0; k < 4; ++k) { + int x = i + dirs[k], y = j + dirs[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y] == 1) { + ok &= dfs(x, y); + } + } + return ok; + } } \ No newline at end of file diff --git a/solution/1900-1999/1905.Count Sub Islands/Solution.py b/solution/1900-1999/1905.Count Sub Islands/Solution.py index e90f8a8dd4e07..cbc621f66b9c6 100644 --- a/solution/1900-1999/1905.Count Sub Islands/Solution.py +++ b/solution/1900-1999/1905.Count Sub Islands/Solution.py @@ -1,13 +1,14 @@ -class Solution: - def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: - def dfs(i, j): - ans = grid1[i][j] == 1 - grid2[i][j] = 0 - for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and grid2[x][y] == 1 and not dfs(x, y): - ans = False - return ans - - m, n = len(grid1), len(grid1[0]) - return sum(grid2[i][j] == 1 and dfs(i, j) for i in range(m) for j in range(n)) +class Solution: + def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int: + def dfs(i: int, j: int) -> int: + ok = grid1[i][j] + grid2[i][j] = 0 + for a, b in pairwise(dirs): + x, y = i + a, j + b + if 0 <= x < m and 0 <= y < n and grid2[x][y] and not dfs(x, y): + ok = 0 + return ok + + m, n = len(grid1), len(grid1[0]) + dirs = (-1, 0, 1, 0, -1) + return sum(dfs(i, j) for i in range(m) for j in range(n) if grid2[i][j]) diff --git a/solution/1900-1999/1905.Count Sub Islands/Solution.ts b/solution/1900-1999/1905.Count Sub Islands/Solution.ts index ada774a57b952..3cc959bd04e95 100644 --- a/solution/1900-1999/1905.Count Sub Islands/Solution.ts +++ b/solution/1900-1999/1905.Count Sub Islands/Solution.ts @@ -1,38 +1,23 @@ function countSubIslands(grid1: number[][], grid2: number[][]): number { - let m = grid1.length, - n = grid1[0].length; + const [m, n] = [grid1.length, grid1[0].length]; let ans = 0; - for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if (grid2[i][j] == 1 && dfs(grid1, grid2, i, j)) { - ++ans; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): number => { + let ok = grid1[i][j]; + grid2[i][j] = 0; + for (let k = 0; k < 4; ++k) { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (x >= 0 && x < m && y >= 0 && y < n && grid2[x][y]) { + ok &= dfs(x, y); } } - } - return ans; -} - -function dfs(grid1: number[][], grid2: number[][], i: number, j: number): boolean { - let m = grid1.length, - n = grid1[0].length; - let ans = true; - if (grid1[i][j] == 0) { - ans = false; - } - grid2[i][j] = 0; - for (let [dx, dy] of [ - [0, 1], - [0, -1], - [1, 0], - [-1, 0], - ]) { - let x = i + dx, - y = j + dy; - if (x < 0 || x > m - 1 || y < 0 || y > n - 1 || grid2[x][y] == 0) { - continue; - } - if (!dfs(grid1, grid2, x, y)) { - ans = false; + return ok; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; j++) { + if (grid2[i][j]) { + ans += dfs(i, j); + } } } return ans;