diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index 97dab4f3..b836705a 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -515,27 +515,31 @@ func largestRectangleArea(heights []int) int { var largestRectangleArea = function(heights) { const len = heights.length; const minLeftIndex = new Array(len); - const maxRigthIndex = new Array(len); + const maxRightIndex = new Array(len); // 记录每个柱子 左边第一个小于该柱子的下标 minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环 for(let i = 1; i < len; i++) { let t = i - 1; // 这里不是用if,而是不断向左寻找的过程 - while(t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t]; + while (t >= 0 && heights[t] >= heights[i]) { + t = minLeftIndex[t]; + } minLeftIndex[i] = t; } // 记录每个柱子 右边第一个小于该柱子的下标 - maxRigthIndex[len - 1] = len; // 注意这里初始化,防止下面while死循环 + maxRightIndex[len - 1] = len; // 注意这里初始化,防止下面while死循环 for(let i = len - 2; i >= 0; i--){ let t = i + 1; // 这里不是用if,而是不断向右寻找的过程 - while(t < len && heights[t] >= heights[i]) t = maxRigthIndex[t]; - maxRigthIndex[i] = t; + while (t <= n && heights[t] > heights[i]) { + t = maxRightIndex[t]; + } + maxRightIndex[i] = t; } // 求和 let maxArea = 0; for(let i = 0; i < len; i++){ - let sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1); + let sum = heights[i] * (maxRightIndex[i] - minLeftIndex[i] - 1); maxArea = Math.max(maxArea , sum); } return maxArea; @@ -543,27 +547,37 @@ var largestRectangleArea = function(heights) { //单调栈 var largestRectangleArea = function(heights) { - let maxArea = 0; - const stack = []; - heights = [0,...heights,0]; // 数组头部加入元素0 数组尾部加入元素0 - for(let i = 0; i < heights.length; i++){ - if(heights[i] > heights[stack[stack.length-1]]){ // 情况三 - stack.push(i); - } else if(heights[i] === heights[stack[stack.length-1]]){ // 情况二 - stack.pop(); // 这个可以加,可以不加,效果一样,思路不同 - stack.push(i); - } else { // 情况一 - while(heights[i] < heights[stack[stack.length-1]]){// 当前bar比栈顶bar矮 - const stackTopIndex = stack.pop();// 栈顶元素出栈,并保存栈顶bar的索引 - let w = i - stack[stack.length -1] - 1; - let h = heights[stackTopIndex] + let maxArea = 0; + const stack = [0]; + heights.push(0); + const n = heights.length; + + for (let i = 1; i < n; i++) { + let top = stack.at(-1); + // 情况三 + if (heights[top] < heights[i]) { + stack.push(i); + } + // 情况二 + if (heights[top] === heights[i]) { + stack.pop(); // 这个可以加,可以不加,效果一样,思路不同 + stack.push(i); + } + // 情况一 + if (heights[top] > heights[i]) { + while (stack.length > 0 && heights[top] > heights[i]) { + // 栈顶元素出栈,并保存栈顶bar的索引 + const h = heights[stack.pop()]; + const left = stack.at(-1) ?? -1; + const w = i - left - 1; // 计算面积,并取最大面积 - maxArea = Math.max(maxArea, w * h); - } - stack.push(i);// 当前bar比栈顶bar高了,入栈 - } - } - return maxArea; + maxArea = Math.max(maxArea, w * h); + top = stack.at(-1); + } + stack.push(i); + } + } + return maxArea; }; //单调栈 简洁 diff --git a/problems/0200.岛屿数量.广搜版.md b/problems/0200.岛屿数量.广搜版.md index e8ed60db..a7dd117b 100644 --- a/problems/0200.岛屿数量.广搜版.md +++ b/problems/0200.岛屿数量.广搜版.md @@ -276,6 +276,52 @@ var numIslands = function (grid) { }; ``` +### TypeScript + +```TypeScript +function numIslands2(grid: string[][]): number { + // 四个方向 + const dir: number[][] = [[0, 1], [1, 0], [-1, 0], [0, -1]]; + const [m, n]: [number, number] = [grid.length, grid[0].length]; + + function dfs(grid: string[][], visited: boolean[][], x: number, y: number) { + const queue: number[][] = [[x, y]]; + while (queue.length !== 0) { + //取出队列头部元素 + const top: number[] = queue.shift()!; + for (let i = 0; i < 4; i++) { + const nextX: number = top[0] + dir[i][0]; + const nextY: number = top[1] + dir[i][1]; + // 越界了,直接跳过 + if (nextX < 0 || nextX >= m || nextY < 0 || nextY >= n) { + continue; + } + if (!visited[nextX][nextY] && grid[nextX][nextY] === '1') { + queue.push([nextX, nextY]); + // 只要加入队列立刻标记 + visited[nextX][nextY] = true; + } + } + } + } + + const visited: boolean[][] = Array.from({ length: m }, _ => new Array(n).fill(false)); + + let result = 0; + for (let i = 0; i < m; i++) { + for (let k = 0; k < n; k++) { + if (!visited[i][k] && grid[i][k] === '1') { + ++result; // 遇到没访问过的陆地,+1 + visited[i][k] = true; + dfs(grid, visited, i, k); // 将与其链接的陆地都标记上 true + } + } + } + return result; +} +``` + + ### Rust ```rust diff --git a/problems/0200.岛屿数量.深搜版.md b/problems/0200.岛屿数量.深搜版.md index 43eb66e1..a4b93c3d 100644 --- a/problems/0200.岛屿数量.深搜版.md +++ b/problems/0200.岛屿数量.深搜版.md @@ -346,6 +346,46 @@ var numIslands = function (grid) { }; ``` +### TypeScript + +```TypeScript +function numIslands(grid: string[][]): number { + // 四个方向 + const dir: number[][] = [[0, 1], [1, 0], [-1, 0], [0, -1]]; + const [m, n]: [number, number] = [grid.length, grid[0].length]; + + function dfs(grid: string[][], visited: boolean[][], x: number, y: number) { + for (let i = 0; i < 4; i++) { + let nextX: number = x + dir[i][0]; + let nextY: number = y + dir[i][1]; + // 越界了,直接跳过 + if (nextX < 0 || nextX >= m || nextY < 0 || nextY >= n) { + continue; + } + // 没有访问过同时是陆地 + if (!visited[nextX][nextY] && grid[nextX][nextY] === '1') { + visited[nextX][nextY] = true; + dfs(grid, visited, nextX, nextY); + } + } + } + + const visited: boolean[][] = Array.from({ length: m }, _ => new Array(n).fill(false)); + + let result: number = 0; + for (let i = 0; i < m; i++) { + for (let k = 0; k < n; k++) { + if (!visited[i][k] && grid[i][k] === '1') { + ++result; // 遇到没访问过的陆地,+1 + visited[i][k] = true; + dfs(grid, visited, i, k); // 将与其链接的陆地都标记上 true + } + } + } + return result; +} +``` + ### Go ```go