diff --git a/solution/0800-0899/0841.Keys and Rooms/README.md b/solution/0800-0899/0841.Keys and Rooms/README.md index e4ae82cc7ec35..0518a89480240 100644 --- a/solution/0800-0899/0841.Keys and Rooms/README.md +++ b/solution/0800-0899/0841.Keys and Rooms/README.md @@ -53,19 +53,25 @@ ## 解法 -### 方法一 +### 方法一:DFS + +我们可以使用深度优先搜索的方法遍历整张图,统计可以到达的节点个数,并利用数组 `vis` 标记当前节点是否访问过,以防止重复访问。 + +最后统计访问过的节点个数,若与节点总数相同则说明可以访问所有节点,否则说明存在无法到达的节点。 + +时间复杂度 $O(n + m)$,空间复杂度 $O(n)$,其中 $n$ 为节点个数,而 $m$ 为边的个数。 ```python class Solution: def canVisitAllRooms(self, rooms: List[List[int]]) -> bool: - def dfs(u): - if u in vis: + def dfs(i: int): + if i in vis: return - vis.add(u) - for v in rooms[u]: - dfs(v) + vis.add(i) + for j in rooms[i]: + dfs(j) vis = set() dfs(0) @@ -74,23 +80,25 @@ class Solution: ```java class Solution { - private List> rooms; - private Set vis; + private int cnt; + private boolean[] vis; + private List> g; public boolean canVisitAllRooms(List> rooms) { - vis = new HashSet<>(); - this.rooms = rooms; + g = rooms; + vis = new boolean[g.size()]; dfs(0); - return vis.size() == rooms.size(); + return cnt == g.size(); } - private void dfs(int u) { - if (vis.contains(u)) { + private void dfs(int i) { + if (vis[i]) { return; } - vis.add(u); - for (int v : rooms.get(u)) { - dfs(v); + vis[i] = true; + ++cnt; + for (int j : g.get(i)) { + dfs(j); } } } @@ -99,55 +107,63 @@ class Solution { ```cpp class Solution { public: - vector> rooms; - unordered_set vis; - bool canVisitAllRooms(vector>& rooms) { - vis.clear(); - this->rooms = rooms; + int n = rooms.size(); + int cnt = 0; + bool vis[n]; + memset(vis, false, sizeof(vis)); + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + ++cnt; + for (int j : rooms[i]) { + dfs(j); + } + }; dfs(0); - return vis.size() == rooms.size(); - } - - void dfs(int u) { - if (vis.count(u)) return; - vis.insert(u); - for (int v : rooms[u]) dfs(v); + return cnt == n; } }; ``` ```go func canVisitAllRooms(rooms [][]int) bool { - vis := make(map[int]bool) - var dfs func(u int) - dfs = func(u int) { - if vis[u] { + n := len(rooms) + cnt := 0 + vis := make([]bool, n) + var dfs func(int) + dfs = func(i int) { + if vis[i] { return } - vis[u] = true - for _, v := range rooms[u] { - dfs(v) + vis[i] = true + cnt++ + for _, j := range rooms[i] { + dfs(j) } } dfs(0) - return len(vis) == len(rooms) + return cnt == n } ``` ```ts function canVisitAllRooms(rooms: number[][]): boolean { const n = rooms.length; - const isOpen = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); const dfs = (i: number) => { - if (isOpen[i]) { + if (vis[i]) { return; } - isOpen[i] = true; - rooms[i].forEach(k => dfs(k)); + vis[i] = true; + for (const j of rooms[i]) { + dfs(j); + } }; dfs(0); - return isOpen.every(v => v); + return vis.every(v => v); } ``` @@ -172,27 +188,4 @@ impl Solution { -### 方法二 - - - -```ts -function canVisitAllRooms(rooms: number[][]): boolean { - const n = rooms.length; - const isOpen = new Array(n).fill(false); - const keys = [0]; - while (keys.length !== 0) { - const i = keys.pop(); - if (isOpen[i]) { - continue; - } - isOpen[i] = true; - keys.push(...rooms[i]); - } - return isOpen.every(v => v); -} -``` - - - diff --git a/solution/0800-0899/0841.Keys and Rooms/README_EN.md b/solution/0800-0899/0841.Keys and Rooms/README_EN.md index 8e779b80242ce..ce04129a2383b 100644 --- a/solution/0800-0899/0841.Keys and Rooms/README_EN.md +++ b/solution/0800-0899/0841.Keys and Rooms/README_EN.md @@ -46,19 +46,25 @@ Since we were able to visit every room, we return true. ## Solutions -### Solution 1 +### Solution 1: Depth-First Search (DFS) + +We can use the Depth-First Search (DFS) method to traverse the entire graph, count the number of reachable nodes, and use an array `vis` to mark whether the current node has been visited to prevent repeated visits. + +Finally, we count the number of visited nodes. If it is the same as the total number of nodes, it means that all nodes can be visited; otherwise, there are nodes that cannot be reached. + +The time complexity is $O(n + m)$, and the space complexity is $O(n)$, where $n$ is the number of nodes, and $m$ is the number of edges. ```python class Solution: def canVisitAllRooms(self, rooms: List[List[int]]) -> bool: - def dfs(u): - if u in vis: + def dfs(i: int): + if i in vis: return - vis.add(u) - for v in rooms[u]: - dfs(v) + vis.add(i) + for j in rooms[i]: + dfs(j) vis = set() dfs(0) @@ -67,23 +73,25 @@ class Solution: ```java class Solution { - private List> rooms; - private Set vis; + private int cnt; + private boolean[] vis; + private List> g; public boolean canVisitAllRooms(List> rooms) { - vis = new HashSet<>(); - this.rooms = rooms; + g = rooms; + vis = new boolean[g.size()]; dfs(0); - return vis.size() == rooms.size(); + return cnt == g.size(); } - private void dfs(int u) { - if (vis.contains(u)) { + private void dfs(int i) { + if (vis[i]) { return; } - vis.add(u); - for (int v : rooms.get(u)) { - dfs(v); + vis[i] = true; + ++cnt; + for (int j : g.get(i)) { + dfs(j); } } } @@ -92,55 +100,63 @@ class Solution { ```cpp class Solution { public: - vector> rooms; - unordered_set vis; - bool canVisitAllRooms(vector>& rooms) { - vis.clear(); - this->rooms = rooms; + int n = rooms.size(); + int cnt = 0; + bool vis[n]; + memset(vis, false, sizeof(vis)); + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + ++cnt; + for (int j : rooms[i]) { + dfs(j); + } + }; dfs(0); - return vis.size() == rooms.size(); - } - - void dfs(int u) { - if (vis.count(u)) return; - vis.insert(u); - for (int v : rooms[u]) dfs(v); + return cnt == n; } }; ``` ```go func canVisitAllRooms(rooms [][]int) bool { - vis := make(map[int]bool) - var dfs func(u int) - dfs = func(u int) { - if vis[u] { + n := len(rooms) + cnt := 0 + vis := make([]bool, n) + var dfs func(int) + dfs = func(i int) { + if vis[i] { return } - vis[u] = true - for _, v := range rooms[u] { - dfs(v) + vis[i] = true + cnt++ + for _, j := range rooms[i] { + dfs(j) } } dfs(0) - return len(vis) == len(rooms) + return cnt == n } ``` ```ts function canVisitAllRooms(rooms: number[][]): boolean { const n = rooms.length; - const isOpen = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); const dfs = (i: number) => { - if (isOpen[i]) { + if (vis[i]) { return; } - isOpen[i] = true; - rooms[i].forEach(k => dfs(k)); + vis[i] = true; + for (const j of rooms[i]) { + dfs(j); + } }; dfs(0); - return isOpen.every(v => v); + return vis.every(v => v); } ``` @@ -165,27 +181,4 @@ impl Solution { -### Solution 2 - - - -```ts -function canVisitAllRooms(rooms: number[][]): boolean { - const n = rooms.length; - const isOpen = new Array(n).fill(false); - const keys = [0]; - while (keys.length !== 0) { - const i = keys.pop(); - if (isOpen[i]) { - continue; - } - isOpen[i] = true; - keys.push(...rooms[i]); - } - return isOpen.every(v => v); -} -``` - - - diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution.cpp b/solution/0800-0899/0841.Keys and Rooms/Solution.cpp index 278efa570087d..662ab58437a04 100644 --- a/solution/0800-0899/0841.Keys and Rooms/Solution.cpp +++ b/solution/0800-0899/0841.Keys and Rooms/Solution.cpp @@ -1,18 +1,21 @@ class Solution { public: - vector> rooms; - unordered_set vis; - bool canVisitAllRooms(vector>& rooms) { - vis.clear(); - this->rooms = rooms; + int n = rooms.size(); + int cnt = 0; + bool vis[n]; + memset(vis, false, sizeof(vis)); + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + ++cnt; + for (int j : rooms[i]) { + dfs(j); + } + }; dfs(0); - return vis.size() == rooms.size(); - } - - void dfs(int u) { - if (vis.count(u)) return; - vis.insert(u); - for (int v : rooms[u]) dfs(v); + return cnt == n; } }; \ No newline at end of file diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution.go b/solution/0800-0899/0841.Keys and Rooms/Solution.go index 4a9b85d122cbd..a027b8b6ac3f9 100644 --- a/solution/0800-0899/0841.Keys and Rooms/Solution.go +++ b/solution/0800-0899/0841.Keys and Rooms/Solution.go @@ -1,15 +1,18 @@ func canVisitAllRooms(rooms [][]int) bool { - vis := make(map[int]bool) - var dfs func(u int) - dfs = func(u int) { - if vis[u] { + n := len(rooms) + cnt := 0 + vis := make([]bool, n) + var dfs func(int) + dfs = func(i int) { + if vis[i] { return } - vis[u] = true - for _, v := range rooms[u] { - dfs(v) + vis[i] = true + cnt++ + for _, j := range rooms[i] { + dfs(j) } } dfs(0) - return len(vis) == len(rooms) + return cnt == n } \ No newline at end of file diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution.java b/solution/0800-0899/0841.Keys and Rooms/Solution.java index fcbafdd5b65b6..ea947ca3caf5e 100644 --- a/solution/0800-0899/0841.Keys and Rooms/Solution.java +++ b/solution/0800-0899/0841.Keys and Rooms/Solution.java @@ -1,21 +1,23 @@ class Solution { - private List> rooms; - private Set vis; + private int cnt; + private boolean[] vis; + private List> g; public boolean canVisitAllRooms(List> rooms) { - vis = new HashSet<>(); - this.rooms = rooms; + g = rooms; + vis = new boolean[g.size()]; dfs(0); - return vis.size() == rooms.size(); + return cnt == g.size(); } - private void dfs(int u) { - if (vis.contains(u)) { + private void dfs(int i) { + if (vis[i]) { return; } - vis.add(u); - for (int v : rooms.get(u)) { - dfs(v); + vis[i] = true; + ++cnt; + for (int j : g.get(i)) { + dfs(j); } } } \ No newline at end of file diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution.py b/solution/0800-0899/0841.Keys and Rooms/Solution.py index e080aaa5c5f1e..fc39a2de98dd3 100644 --- a/solution/0800-0899/0841.Keys and Rooms/Solution.py +++ b/solution/0800-0899/0841.Keys and Rooms/Solution.py @@ -1,11 +1,11 @@ class Solution: def canVisitAllRooms(self, rooms: List[List[int]]) -> bool: - def dfs(u): - if u in vis: + def dfs(i: int): + if i in vis: return - vis.add(u) - for v in rooms[u]: - dfs(v) + vis.add(i) + for j in rooms[i]: + dfs(j) vis = set() dfs(0) diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution.ts b/solution/0800-0899/0841.Keys and Rooms/Solution.ts index 86e8caaeae2c7..4f3594f149389 100644 --- a/solution/0800-0899/0841.Keys and Rooms/Solution.ts +++ b/solution/0800-0899/0841.Keys and Rooms/Solution.ts @@ -1,13 +1,15 @@ function canVisitAllRooms(rooms: number[][]): boolean { const n = rooms.length; - const isOpen = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); const dfs = (i: number) => { - if (isOpen[i]) { + if (vis[i]) { return; } - isOpen[i] = true; - rooms[i].forEach(k => dfs(k)); + vis[i] = true; + for (const j of rooms[i]) { + dfs(j); + } }; dfs(0); - return isOpen.every(v => v); + return vis.every(v => v); } diff --git a/solution/0800-0899/0841.Keys and Rooms/Solution2.ts b/solution/0800-0899/0841.Keys and Rooms/Solution2.ts deleted file mode 100644 index 613a3c81b64d4..0000000000000 --- a/solution/0800-0899/0841.Keys and Rooms/Solution2.ts +++ /dev/null @@ -1,14 +0,0 @@ -function canVisitAllRooms(rooms: number[][]): boolean { - const n = rooms.length; - const isOpen = new Array(n).fill(false); - const keys = [0]; - while (keys.length !== 0) { - const i = keys.pop(); - if (isOpen[i]) { - continue; - } - isOpen[i] = true; - keys.push(...rooms[i]); - } - return isOpen.every(v => v); -} diff --git a/solution/0800-0899/0848.Shifting Letters/README.md b/solution/0800-0899/0848.Shifting Letters/README.md index c22b87517f3ab..5b7a964da556c 100644 --- a/solution/0800-0899/0848.Shifting Letters/README.md +++ b/solution/0800-0899/0848.Shifting Letters/README.md @@ -61,6 +61,18 @@ +```python +class Solution: + def shiftingLetters(self, s: str, shifts: List[int]) -> str: + n, t = len(s), 0 + s = list(s) + for i in range(n - 1, -1, -1): + t += shifts[i] + j = (ord(s[i]) - ord('a') + t) % 26 + s[i] = ascii_lowercase[j] + return ''.join(s) +``` + ```python class Solution: def shiftingLetters(self, s: str, shifts: List[int]) -> str: @@ -130,22 +142,4 @@ func shiftingLetters(s string, shifts []int) string { -### 方法二 - - - -```python -class Solution: - def shiftingLetters(self, s: str, shifts: List[int]) -> str: - n, t = len(s), 0 - s = list(s) - for i in range(n - 1, -1, -1): - t += shifts[i] - j = (ord(s[i]) - ord('a') + t) % 26 - s[i] = ascii_lowercase[j] - return ''.join(s) -``` - - - diff --git a/solution/0800-0899/0848.Shifting Letters/README_EN.md b/solution/0800-0899/0848.Shifting Letters/README_EN.md index 92d7459c98463..cbd0973eb72b9 100644 --- a/solution/0800-0899/0848.Shifting Letters/README_EN.md +++ b/solution/0800-0899/0848.Shifting Letters/README_EN.md @@ -51,6 +51,18 @@ After shifting the first 3 letters of s by 9, we have "rpl", the answe +```python +class Solution: + def shiftingLetters(self, s: str, shifts: List[int]) -> str: + n, t = len(s), 0 + s = list(s) + for i in range(n - 1, -1, -1): + t += shifts[i] + j = (ord(s[i]) - ord('a') + t) % 26 + s[i] = ascii_lowercase[j] + return ''.join(s) +``` + ```python class Solution: def shiftingLetters(self, s: str, shifts: List[int]) -> str: @@ -120,22 +132,4 @@ func shiftingLetters(s string, shifts []int) string { -### Solution 2 - - - -```python -class Solution: - def shiftingLetters(self, s: str, shifts: List[int]) -> str: - n, t = len(s), 0 - s = list(s) - for i in range(n - 1, -1, -1): - t += shifts[i] - j = (ord(s[i]) - ord('a') + t) % 26 - s[i] = ascii_lowercase[j] - return ''.join(s) -``` - - -