1
头图

Zero title: Algorithm (leetcode, with mind map + all solutions) (200) number of islands out of 300 questions

a topic description

题目描述
题目描述

Two solutions overview (mind map)

思维导图

All three solutions

1 Scenario 1

1) Code:

 // 方案1 “自己。模拟 - 标记法”。

// 思路:
// 1)状态初始化:m = grid.length, n = grid[0].length; 。
// tempMap = new Map(), resMap = getMapByGrid(), resCount = 0; 。
// 2)核心:循环处理 —— 条件为 存在未被访问过的陆地 。
// 3)返回结果 resCount 。
var numIslands = function(grid) {
    const getMapByGrid = () => {
        let resMap = new Map();

        for (let i = 0; i < m; i++) {
            for (let j = 0; j < n; j++) {
                if (grid[i][j] === '1') {
                    const tempVal = `${i}#${j}`;
                    resMap.set(tempVal, 1);
                }
            }
        }

        return resMap;
    };

    // 1)状态初始化:m = grid.length, n = grid[0].length; 。
    // tempMap = new Map(), resMap = getMapByGrid(), resCount = 0; 。
    const m = grid.length,
        n = grid[0].length;
    let // tempMap:目前已被访问过的陆地。
        tempMap = new Map(),
        resMap = getMapByGrid(),
        resCount = 0;

    // 2)核心:循环处理 —— 条件为 存在未被访问过的陆地 。
    while (resMap.size !== 0) {
        for (const [key, val] of resMap) {
            if (!tempMap.has(key)) {
                tempMap.set(key, 1);
                let tempQueue = [key];
                
                while (tempQueue.length !== 0) {
                    const key = tempQueue.shift(),
                        [tempI, tempJ] = key.split('#').map(v => parseInt(v));
                    
                    // 标记为已被访问。
                    resMap.delete(key);

                    // 4个方向的访问。
                    // 上
                    if (tempI - 1 >= 0 && grid[tempI - 1][tempJ] === '1') {
                        const key = `${tempI - 1}#${tempJ}`;
                        if (!tempMap.has(key)) {
                            tempQueue.push(key);
                            tempMap.set(key, 1);
                        }
                    }
                    // 下

                    if (tempI + 1 < m && grid[tempI + 1][tempJ] === '1') {
                        const key = `${tempI + 1}#${tempJ}`;
                        if (!tempMap.has(key)) {
                            tempQueue.push(key);
                            tempMap.set(key, 1);
                        }
                    }
                    // 左
                    if (tempJ - 1 >= 0 && grid[tempI][tempJ - 1] === '1') {
                        const key = `${tempI}#${tempJ - 1}`;
                        if (!tempMap.has(key)) {
                            tempQueue.push(key);
                            tempMap.set(key, 1);
                        }
                    }
                    // 右
                    if (tempJ + 1 < n && grid[tempI][tempJ + 1] === '1') {
                        const key = `${tempI}#${tempJ + 1}`;
                        if (!tempMap.has(key)) {
                            tempQueue.push(key);
                            tempMap.set(key, 1);
                        }
                    }
                }

                // 当前岛屿无法再次连接到任何陆地了。
                resCount++;
            }
            break;
        }
    }

    // 3)返回结果 resCount 。
    return resCount;
};

2 Option 2

1) Code:

 // 方案2 “自己。深度优先搜索法”。
// 参考:
// 1)https://leetcode.cn/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/

// 思路:
// 1)状态初始化:m = grid.length, n = grid[0].length; 。
// resCount = 0;
// 2)核心:遍历 grid 。
// 2.1)若 当前的格子为 陆地,则 岛屿数量增加1 并 执行深度搜索函数 —— dfs(i, j) 。
// 3)返回结果 resCount 。
var numIslands = function(grid) {
    // 深度搜索(实现:递归)
    const dfs = (curI = 0, curJ = 0) => {
        // 1)递归出口:其实被隐藏起来 —— 当坐标超出格子范围 或 坐标不符合条件时。

        // 2)递归主体。
        // 2.1)当前陆地置为 水 。
        grid[curI][curJ] = '0';

        // 2.2)上下左右,四个方向执行深度搜索。
        if (curI - 1 >= 0 && grid[curI - 1][curJ] === '1') {
            dfs(curI - 1, curJ);
        }
        if (curI + 1 < m && grid[curI + 1][curJ] === '1') {
            dfs(curI + 1, curJ);
        }
        if (curJ - 1 >= 0 && grid[curI][curJ - 1] === '1') {
            dfs(curI, curJ - 1);
        }
        if (curJ + 1 < n && grid[curI][curJ + 1] === '1') {
            dfs(curI, curJ + 1);
        }
    };

    // 1)状态初始化:m = grid.length, n = grid[0].length; 。
    // resCount = 0;
    const m = grid.length,
        n = grid[0].length;
    let resCount = 0;

    // 2)核心:遍历 grid 。
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            // 2.1)若 当前的格子为 陆地,则 岛屿数量增加1 并 执行深度搜索函数 —— dfs(i, j) 。
            if (grid[i][j] === '1') {
                resCount++;
                dfs(i, j);
            }
        }
    }

    // 3)返回结果 resCount 。
    return resCount;
};

3 Scenario 3

1) Code:

 // 方案3 “广度优先搜索法(本质:跟方案1差不多)”。
// 参考:
// 1)https://leetcode.cn/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/

// 思路:
// 1)状态初始化:m = grid.length, n = grid[0].length;
// resCount = 0; 。
// 2)核心:2层循环的遍历。
// 2.1)若 当前位置为 陆地 ,特殊处理,
// 并 进行 广度优先(使用队列 queue )的遍历处理。
// 3)返回结果 resCount 。
var numIslands = function(grid) {
    // 1)状态初始化:m = grid.length, n = grid[0].length;
    // resCount = 0; 。
    const m = grid.length,
        n = grid[0].length;
    let resCount = 0;

    // 2)核心:2层循环的遍历。
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            // 2.1)若 当前位置为 陆地 ,特殊处理,
            // 并 进行 广度优先(使用队列 queue )的遍历处理。
            if (grid[i][j] === '1') {
                grid[i][j] = '0';
                resCount++;
                let queue = [[i, j]];
                
                while (queue.length !== 0) {
                    const [tempI, tempJ] = queue.shift();
                    // 上下左右,4个方向。
                    if (tempI - 1 >= 0 &&grid[tempI - 1][tempJ] === '1') {
                        queue.push([tempI - 1, tempJ]);
                        grid[tempI - 1][tempJ] = '0';
                    }
                    if (tempI + 1 < m &&grid[tempI + 1][tempJ] === '1') {
                        queue.push([tempI + 1, tempJ]);
                        grid[tempI + 1][tempJ] = '0';
                    }
                    if (tempJ - 1 >= 0 &&grid[tempI][tempJ - 1] === '1') {
                        queue.push([tempI, tempJ - 1]);
                        grid[tempI][tempJ - 1] = '0';
                    }
                    if (tempJ + 1 < n &&grid[tempI][tempJ + 1] === '1') {
                        queue.push([tempI, tempJ + 1]);
                        grid[tempI][tempJ + 1] = '0';
                    }
                }
            }
        }
    }

    // 3)返回结果 resCount 。
    return resCount;
}

4 Option 4

1) Code:

 // 方案4 “并查集法”。
// 参考:
// 1)https://leetcode.cn/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/

// 注:有问题,通过 12 / 49 。TODO:排查问题 && 重新手撕。
var numIslands = function(grid) {
    class Unionfind {
        constructor() {
            let count = 0,
                parent = [],
                rank = [];
            
            for (let i = 0; i < m; i++) {
                for (let j = 0; j < n; j++) {
                    const tempIndex = n * i + j;
                    if (grid[i][j] === '1') {
                        parent[tempIndex] = tempIndex;
                        count++;
                    }
                    // ?
                    rank[tempIndex] = 0;
                }
            }

            this.count = count;
            this.parent = parent;
            this.rank = rank;
        }

        find(index) {
            const {parent} = this;
            if (parent[index] !== index) {
                // 找到该坐标最开始的“祖先”?
                parent[index] = this.find(parent[index]);
            }
            
            this.parent = parent;
            return parent[index];
        }

        union(index_1, index_2) {
            let {rank, parent, count} = this;

            const root_1 = this.find(index_1),
                root_2 = this.find(index_2);
            
            if (root_1 !== root_2) {
                if (rank[root_1] > rank[root_2]) {
                    parent[root_2] = root_1;
                }
                else if (rank[root_1] < rank[root_2]) {
                    parent[root_1] = root_2;
                }
                else {
                    parent[root_2] = root_1;
                    // ?
                    rank[root_1] += 1;
                }
                count--;
            }
            
            this.count = count;
            this.parent = parent;
            this.rank = rank;
        }

        getCount() {
            const {count} = this;

            return count;
        }
    }

    const m = grid.length,
        n = grid[0].length;
    let unionfind = new Unionfind();

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === '1') {
                grid[i][j] = '0';
            }

            // 上下左右,4个方向。
            const tempIndex = n * i + j;
            if (i - 1 >= 0 && grid[i - 1][j] === '1') {
                unionfind.union(tempIndex, n * (i - 1) + j);
            }
            if (i + 1 < m && grid[i + 1][j] === '1') {
                unionfind.union(tempIndex, n * (i + 1) + j);
            }
            if (j - 1 >= 0 && grid[i][j - 1] === '1') {
                unionfind.union(tempIndex, n * i + (j - 1));
            }
            if (j + 1 < n && grid[i][j + 1] === '1') {
                unionfind.union(tempIndex, n * i + (j + 1));
            }
        }
    }

    return unionfind.getCount();
}

Four resource sharing & more

1 Historical Articles - Overview

Article name solution reading volume
1. Two Sum 3 types in total 2.7k+
2. Add Two Numbers 4 types in total 2.7k+
3. Longest Substring Without Repeating Characters 3 types in total 2.6k+
4. Find the Median of Two Sorted Arrays 3 types in total 2.8k+
5. Longest Palindromic Substring 4 types in total 2.8k+
6. ZigZag Conversion 2 types in total 1.9k+
7. Reverse Integer 2 types in total 2.4k+
8. String to Integer (atoi) 3 types in total 4.2k+
9. Palindrome Number 3 types in total 4.3k+
11. Container With Most Water 5 in total 4.0k+
12. Integer to Roman 3 types in total 3.2k+
13. Roman to Integer 3 types in total 3.8k+
14. Longest Common Prefix 4 types in total 3.0k+
15. The Sum of Three Numbers (3Sum) 3 types in total 60.7k+
16. 3Sum Closest 3 types in total 4.7k+
17. Letter Combinations of a Phone Number 3 types in total 3.1k+
18. The sum of four numbers (4Sum) 4 types in total 11.5k+
19. Remove Nth Node From End of List 4 types in total 1.2k+
20. Valid Parentheses 2 types in total 1.8k+
21. Merge Two Sorted Lists 3 types in total 1.2k+
22. Generate Parentheses 4 types in total 1.1k+
23. Merge k Sorted Lists 4 types in total 0.9k+
24. Swap Nodes in Pairs 3 types in total 0.5k+
25. Reverse Nodes in k-Group 5 in total 1.3k+
26. Remove Duplicates from Sorted Array 4 types in total 1.3k+
27. Remove Element 4 types in total 0.4k+
28. Implement strStr() (Implement strStr()) 5 in total 0.8k+
29. Divide Two Integers 4 types in total 0.6k+
30. Substring with Concatenation of All Words 3 types in total 0.6k+
31. Next Permutation 2 types in total 0.8k+
32. Longest Valid Parentheses 2 types in total 1.4k+
33. Search in Rotated Sorted Array 3 types in total 1.0k+
34. Find First and Last Position of Element in Sorted Array 3 types in total 0.5k+
35. Search Insert Position 3 types in total 0.3k+
36. Valid Sudoku 1 in total 0.6k+
38. Count and Say 5 in total 1.1k+
39. Combination Sum 3 types in total 1.4k+
40. Combination Sum II 2 types in total 1.6k+
41. First Missing Positive 3 types in total 1.2k+
53. Maximum Subarray Sum (Maximum Subarray) 3 types in total 0.3k+
88. Merge Sorted Array 3 types in total 0.4k+
102. Binary Tree Level Order Traversal 3 types in total 0.4k+
146. LRU Cache (LRU Cache) 2 types in total 0.5k+
206. Reverse Linked List 3 types in total 1.0k+
215. Kth Largest Element in an Array 3 types in total 0.5k+
236. Lowest Common Ancestor of a Binary Tree 3 types in total 0.1k+

刷题进度 - LeetCode:527 / 2662 、《剑指offer》:66 / 66

2 Introduction to bloggers

Code Farmer Sanshao, a blogger dedicated to writing minimalist but complete problem solutions (algorithms ).
Focus on one question, multiple solutions, structured thinking , welcome to brush through LeetCode ~


码农三少
54 声望8 粉丝