Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update solutions to lc problem: No.0841,0848 #2260

Merged
merged 1 commit into from
Jan 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 57 additions & 64 deletions solution/0800-0899/0841.Keys and Rooms/README.md
Original file line number Diff line number Diff line change
@@ -53,19 +53,25 @@

## 解法

### 方法一
### 方法一:DFS

我们可以使用深度优先搜索的方法遍历整张图,统计可以到达的节点个数,并利用数组 `vis` 标记当前节点是否访问过,以防止重复访问。

最后统计访问过的节点个数,若与节点总数相同则说明可以访问所有节点,否则说明存在无法到达的节点。

时间复杂度 $O(n + m)$,空间复杂度 $O(n)$,其中 $n$ 为节点个数,而 $m$ 为边的个数。

<!-- tabs:start -->

```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<List<Integer>> rooms;
private Set<Integer> vis;
private int cnt;
private boolean[] vis;
private List<List<Integer>> g;

public boolean canVisitAllRooms(List<List<Integer>> 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<vector<int>> rooms;
unordered_set<int> vis;

bool canVisitAllRooms(vector<vector<int>>& rooms) {
vis.clear();
this->rooms = rooms;
int n = rooms.size();
int cnt = 0;
bool vis[n];
memset(vis, false, sizeof(vis));
function<void(int)> 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 {

<!-- tabs:end -->

### 方法二

<!-- tabs:start -->

```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);
}
```

<!-- tabs:end -->

<!-- end -->
121 changes: 57 additions & 64 deletions solution/0800-0899/0841.Keys and Rooms/README_EN.md
Original file line number Diff line number Diff line change
@@ -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.

<!-- tabs:start -->

```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<List<Integer>> rooms;
private Set<Integer> vis;
private int cnt;
private boolean[] vis;
private List<List<Integer>> g;

public boolean canVisitAllRooms(List<List<Integer>> 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<vector<int>> rooms;
unordered_set<int> vis;

bool canVisitAllRooms(vector<vector<int>>& rooms) {
vis.clear();
this->rooms = rooms;
int n = rooms.size();
int cnt = 0;
bool vis[n];
memset(vis, false, sizeof(vis));
function<void(int)> 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 {

<!-- tabs:end -->

### Solution 2

<!-- tabs:start -->

```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);
}
```

<!-- tabs:end -->

<!-- end -->
Loading