Skip to content

Problem 200 #38

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

Merged
merged 3 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ As I work through this list I figure I would make a GitHub repo with my solution
37. [Product of Array Except Self #238](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/product-of-array-238.md)
38. [Min Stack #155](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/min-stack-155.md)
39. [Validate Binary Search Tree #98](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/validate-binary-tree-98.md)
40. Number of Islands #200
40. [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)
41. Rotting Oranges #994
42. Search in Rotated Sorted Array #33
43. Combination Sum #39
Expand Down Expand Up @@ -111,6 +111,7 @@ In order to practice with similar data structures I'll be placing each problem i
- [Meeting Rooms II](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/meeting-rooms-ii-253.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)
- [Product of Array Except Self #238](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/product-of-array-238.md)
- [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)

### Queue

Expand All @@ -120,6 +121,7 @@ In order to practice with similar data structures I'll be placing each problem i
- [Maximum Depth of Binary Tree #104](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/depth-binary-tree-104.md)
- [Binary Tree Level Order Traversal #102](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/binary-tree-level-102.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)
- [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)

### Stack

Expand All @@ -131,6 +133,7 @@ In order to practice with similar data structures I'll be placing each problem i
- [Evaluate Reverse Polish Notation #150](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/polish-notation-150.md)
- [Min Stack #155](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/min-stack-155.md)
- [Validate Binary Search Tree #98](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/validate-binary-tree-98.md)
- [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)

### Linked Lists

Expand Down Expand Up @@ -217,6 +220,7 @@ Within the problems above there are several patterns that often occur. I plan to
- [Number of Provinces #547](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-provinces-547.md)
- [Course Schedule #207](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/course-schedule-207.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)
- [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)

### Depth First Search

Expand All @@ -230,6 +234,7 @@ Within the problems above there are several patterns that often occur. I plan to
- [Number of Provinces #547](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-provinces-547.md)
- [Course Schedule #207](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/course-schedule-207.md)
- [Validate Binary Search Tree #98](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/validate-binary-tree-98.md)
- [Number of Islands #200](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-islands-200.md)

### Divide & Conquer

Expand Down
148 changes: 148 additions & 0 deletions medium/number-of-islands-200.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Number of Islands

Page on leetcode: https://leetcode.com/problems/number-of-islands/

## Problem Statement

Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.

An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

### Constraints

- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 300
- grid[i][j] is '0' or '1'.

### Example

```
Input: grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1
```

```
Input: grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
Output: 3
```

## Solution

- Only 1's that are horizontal/vertical connected count, no diagonals
- Need to store nodes that have been visited, maybe a set
- DFS or BFS search in four directions

### Pseudocode

1. Create set
2. Create counter for islands
3. Iterate thru matrix nest i j loops
4. If cell is 1 and isn't in set call dfs function
5. number of islands++
6. create dfs recursive helper
7. if cell is 1 and in bounds and not in set
8. then add to set
9. recursive calls on all four directions
10. return num of islands

### Initial Solution

This solution has a time and space complexity O(mn).

```javascript
const numIslands = function (grid) {
const h = grid.length;
const w = grid[0].length;

let totalIslands = 0;

// Iterate through the matrix
for (let i = 0; i < h; i++) {
for (let j = 0; j < w; j++) {
if (grid[i][j] === '1') {
dfs(i, j);
totalIslands++;
}
}
}
return totalIslands;

// DFS helper function
function dfs(i, j) {
// Check for in bounds
const bounds = i >= 0 && i < h && j >= 0 && j < w;

// If valid cell add to set and start recursion
if (bounds && grid[i][j] === '1') {
grid[i][j] = '2';
dfs(i + 1, j);
dfs(i, j + 1);
dfs(i - 1, j);
dfs(i, j - 1);
}
}
};
```

### Optimized Solution

The following solution has the same time and space complexity, but is approach with iterative BFS instead of recursive DFS. You can see and explanation here: https://www.youtube.com/watch?v=pV2kpPD66nE

```javascript
const numIslands = function (grid) {
const h = grid.length;
const w = grid[0].length;
const visited = new Set();
let totalIslands = 0;

// Iterate through the matrix
for (let i = 0; i < h; i++) {
for (let j = 0; j < w; j++) {
if (grid[i][j] === '1' && !visited.has(`${i}, ${j}`)) {
bfs(i, j);
totalIslands++;
}
}
}

return totalIslands;

// BFS helper function
function bfs(i, j) {
const queue = [];
visited.add(`${i}, ${j}`);
queue.push([i, j]);

while (queue.length > 0) {
const [i, j] = queue.shift();
const dir = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0],
];
for (let d of dir) {
const row = i + d[0];
const col = j + d[1];
// Check for in bounds
const bounds = row >= 0 && row < h && col >= 0 && col < w;
if (bounds && !visited.has(`${row}, ${col}`) && grid[row][col] === '1') {
visited.add(`${row}, ${col}`);
queue.push([row, col]);
}
}
}
}
};
```