diff --git "a/problems/1365.\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227.md" "b/problems/1365.\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227.md" index 61b548abf8..60f1403259 100755 --- "a/problems/1365.\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227.md" +++ "b/problems/1365.\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227.md" @@ -134,6 +134,34 @@ public int[] smallerNumbersThanCurrent(int[] nums) { } ``` +> 桶排序: + +```java +/*** + * nums[i]在[0, 100]之间, 可以使用桶排序记录数字个数, 比当前数字nums[i]小的就是[0, nums[i])范围的总数 + * 以[8, 1, 2, 2, 3]为例, 桶排序记录后为[0, 1, 2, 1, 0, 0, 0, 0, 1, ...], + * 时间复杂度O(n * k) + * 空间复杂度O(1) + * @param nums + * @return + */ +public int[] smallerNumbersThanCurrent(int[] nums) { + // nums[i]在[0, 100]之间, 记录nums[i]出现次数 + int[] hash = new int[101]; + int n = nums.length; + + for (int num : nums) hash[num]++; + for (int i = 0; i < n; i++) { + int cnt = 0; + for (int j = 0; j < nums[i]; j++) { + cnt += hash[j]; + } + nums[i] = cnt; + } + return nums; +} +``` + ### Python: > 暴力法: @@ -251,6 +279,31 @@ var smallerNumbersThanCurrent = function(nums) { }; ``` +>桶排序 + +```js +/** + * nums[i]在[0, 100]之间, 可以使用桶排序记录数字个数, 比当前数字nums[i]小的就是[0, nums[i])范围的总数 + * 以[8, 1, 2, 2, 3]为例, 桶排序记录后为[0, 1, 2, 1, 0, 0, 0, 0, 1, ...], + * 时间复杂度O(n * k) + * 空间复杂度O(1) + * @param {number[]} nums + * @return {number[]} + */ +var smallerNumbersThanCurrent = function(nums) { + let n = nums.length + let hash = new Array(101).fill(0) + + for (let num of nums) hash[num]++ + for (let i = 0; i < n; i++) { + let cnt = 0; + for (let j = 0; j < nums[i]; j++) cnt += hash[j] + nums[i] = cnt + } + return nums +}; +``` + ### TypeScript: > 暴力法: @@ -308,4 +361,3 @@ impl Solution { } ``` - diff --git "a/problems/kamacoder/0099.\345\262\233\345\261\277\347\232\204\346\225\260\351\207\217\346\267\261\346\220\234.md" "b/problems/kamacoder/0099.\345\262\233\345\261\277\347\232\204\346\225\260\351\207\217\346\267\261\346\220\234.md" index fb824aeff2..c266b03e35 100644 --- "a/problems/kamacoder/0099.\345\262\233\345\261\277\347\232\204\346\225\260\351\207\217\346\267\261\346\220\234.md" +++ "b/problems/kamacoder/0099.\345\262\233\345\261\277\347\232\204\346\225\260\351\207\217\346\267\261\346\220\234.md" @@ -188,40 +188,39 @@ int main() { import java.util.Scanner; public class Main { - public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}}; - public static void dfs(boolean[][] visited,int x,int y ,int [][]grid) - { + public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + + public static void dfs(boolean[][] visited, int x, int y, int[][] grid) { for (int i = 0; i < 4; i++) { - int nextX=x+dir[i][0]; - int nextY=y+dir[i][1]; - if(nextY<0||nextX<0||nextX>= grid.length||nextY>=grid[0].length) + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + if (nextY < 0 || nextX < 0 || nextX >= grid.length || nextY >= grid[0].length) continue; - if(!visited[nextX][nextY]&&grid[nextX][nextY]==1) - { - visited[nextX][nextY]=true; - dfs(visited,nextX,nextY,grid); + if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) { + visited[nextX][nextY] = true; + dfs(visited, nextX, nextY, grid); } } } + public static void main(String[] args) { Scanner sc = new Scanner(System.in); - int m= sc.nextInt(); + int m = sc.nextInt(); int n = sc.nextInt(); int[][] grid = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { - grid[i][j]=sc.nextInt(); + grid[i][j] = sc.nextInt(); } } - boolean[][]visited =new boolean[m][n]; + boolean[][] visited = new boolean[m][n]; int ans = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { - if(!visited[i][j]&&grid[i][j]==1) - { + if (!visited[i][j] && grid[i][j] == 1) { ans++; - visited[i][j]=true; - dfs(visited,i,j,grid); + visited[i][j] = true; + dfs(visited, i, j, grid); } } } @@ -230,6 +229,56 @@ public class Main { } ``` +> 针对版本一,使用grid数组代替visited数组的标记功能 + +```java +import java.util.Scanner; + +public class Main { + public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + + /** + * 使用grid数组代替原visited数组的标记功能, 将当前访问从陆地(1)修改为水(0) + */ + public static void dfs(int x, int y, int[][] grid) { + for (int i = 0; i < 4; i++) { + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + if (nextY < 0 || nextX < 0 || nextX >= grid.length || nextY >= grid[0].length) continue; + if (grid[nextX][nextY] == 1) { + // 使用grid数组代替原visited数组, 将当前从陆地(1)修改为水(0), 后续这个位置也不会再进行dfs搜索 + grid[nextX][nextY] = 0; + dfs(nextX, nextY, grid); + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int m = sc.nextInt(); + int n = sc.nextInt(); + int[][] grid = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + grid[i][j] = sc.nextInt(); + } + } + int ans = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + ans++; + // 使用grid数组代替原visited数组, 将当前从陆地(1)修改为水(0), 后续这个位置也不会再进行dfs搜索 + grid[i][j] = 0; + dfs(i, j, grid); + } + } + } + System.out.println(ans); + } +} +``` + ### Python 版本一 diff --git "a/problems/kamacoder/\345\233\276\350\256\272\346\267\261\346\220\234\347\220\206\350\256\272\345\237\272\347\241\200.md" "b/problems/kamacoder/\345\233\276\350\256\272\346\267\261\346\220\234\347\220\206\350\256\272\345\237\272\347\241\200.md" index 29256de466..f7caf06838 100644 --- "a/problems/kamacoder/\345\233\276\350\256\272\346\267\261\346\220\234\347\220\206\350\256\272\345\237\272\347\241\200.md" +++ "b/problems/kamacoder/\345\233\276\350\256\272\346\267\261\346\220\234\347\220\206\350\256\272\345\237\272\347\241\200.md" @@ -162,7 +162,7 @@ if (终止条件) { } ``` -终止添加不仅是结束本层递归,同时也是我们收获结果的时候。 +终止条件不仅是结束本层递归,同时也是我们收获结果的时候。 另外,其实很多dfs写法,没有写终止条件,其实终止条件写在了, 隐藏在下面dfs递归的逻辑里了,也就是不符合条件,直接不会向下递归。这里如果大家不理解的话,没关系,后面会有具体题目来讲解。 @@ -195,4 +195,3 @@ for (选择:本节点所连接的其他节点) { 后面我也会给大家安排具体练习的题目,依旧是代码随想录的风格,循序渐进由浅入深! -