Hanota
经典递归问题,从这道题学到的关于递归的思想挺多的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public void move (int size, List<Integer> A, List<Integer> B, List<Integer> C) { if (size == 1 ){ C.add(A.remove(A.size() - 1 )); return ; } move(size - 1 , A, C, B); C.add(A.remove(A.size() - 1 )); move(size - 1 , B, A, C); } public void hanota (List<Integer> A, List<Integer> B, List<Integer> C) { move(A.size(), A, B, C); } }
Plaint
经典的dfs问题,好像有一个比较高大上的名字叫做漫水算法?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public void dfs (int [][] image, int [][] sign, int sr, int sc, int newColor) { if (sign[sr][sc] == 1 ){ return ; } int [][] step = {{1 , 0 }, {-1 , 0 }, {0 , 1 }, {0 , -1 }}; int width = image.length; int length = image[0 ].length; sign[sr][sc] = 1 ; int temp = image[sr][sc]; image[sr][sc] = newColor; for (int i = 0 ; i < 4 ; i++) { int row = sr + step[i][0 ]; int col = sc + step[i][1 ]; if (row >= width || row < 0 || col >= length || col < 0 || sign[row][col] == 1 || temp != image[row][col]){ continue ; } dfs(image, sign, row, col, newColor); } } public int [][] floodFill(int [][] image, int sr, int sc, int newColor) { int [][] sign = new int [image.length][image[0 ].length]; dfs(image, sign ,sr, sc, newColor); return image; } }
岛屿数量
刷LeetCode第一次一遍过😁
判断是否为水,或判断标记是否走过
dfs确定连在一起的岛的范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution { int height = 0 ; int width = 0 ; int [][] step = {{1 ,0 },{-1 ,0 },{0 ,1 },{0 ,-1 }}; public void numIslandsDfs (char [][] grid, int row, int col, int [][] book) { if (row < 0 || row >= height || col < 0 || col >= width)return ; else if (grid[row][col] == '0' || book[row][col] == 1 )return ; book[row][col] = 1 ; for (int i = 0 ; i < 4 ; i++) { int post_x = row + step[i][0 ]; int post_y = col + step[i][1 ]; numIslandsDfs(grid, post_x, post_y, book); } } public int numIslands (char [][] grid) { int count = 0 ; height = grid.length; width = grid[0 ].length; int book[][]= new int [grid.length][grid[0 ].length]; for (int i = 0 ; i < height; i++) { for (int j = 0 ; j < width; j++) { if (grid[i][j] == '0' || book[i][j] == 1 ) { continue ; }else { numIslandsDfs(grid, i, j, book); count++; } } } return count; } }
矩阵中的路径
1 2 3 4 5 6 7 思路如下 将返回值设置为false 如果dfs出一个完整的单词链则将返回值设置为true,并且直接break 遍历表,只对应单词的首字符 首字母存在就直接进行dfs遍历,遍历的方向只有四个方向 回溯,如果道路不符合需要把之前走过的路全部清0
第一次写的代码最后三个检测点死活不能过,下面贴第一次写的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { int [][] step = {{1 ,0 },{-1 ,0 },{0 ,1 },{0 ,-1 }}; int height = 0 ; int width = 0 ; boolean objRet = false ; public void existDfs (char [][] board, int row, int col, int [][] book, char [] wordArray, int wordIndex) { if (wordIndex == wordArray.length){ this .objRet = true ; return ; } if (row >= height || row < 0 || col >= width || col < 0 ) return ; else if (book[row][col] == 1 || board[row][col] != wordArray[wordIndex]) return ; book[row][col] = 1 ; wordIndex++; for (int i = 0 ; i < 4 ; i++) { int post_x = step[i][0 ] + row; int post_y = step[i][1 ] + col; existDfs(board, post_x, post_y, book, wordArray, wordIndex); } book[row][col] = 0 ; } public boolean exist (char [][] board, String word) { char [] wordArray = word.toCharArray(); height = board.length; width = board[0 ].length; for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { if (board[i][j] == wordArray[0 ]){ int [][] book = new int [height][width]; existDfs(board,i,j,book,wordArray,0 ); } } } return this .objRet; } }
第二次写的代码,虽然过了,但是效率也太低了。。。服了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class Solution { int [][] step = {{1 ,0 },{-1 ,0 },{0 ,1 },{0 ,-1 }}; int height = 0 ; int width = 0 ; public boolean existDfs (char [][] board, int row, int col, int [][] book, char [] wordArray, int wordIndex) { if (row >= height || row < 0 || col >= width || col < 0 )return false ; else if (board[row][col] != wordArray[wordIndex] || book[row][col] == 1 )return false ; if (wordIndex == wordArray.length-1 )return true ; boolean ret = false ; for (int i = 0 ; i < 4 ; i++) { int post_x = step[i][0 ] + row; int post_y = step[i][1 ] + col; book[row][col] = 1 ; ret = existDfs(board, post_x, post_y, book, wordArray, wordIndex+1 ); if (ret == true )break ; book[row][col] = 0 ; } return ret; } public boolean exist (char [][] board, String word) { char [] wordArray = word.toCharArray(); height = board.length; width = board[0 ].length; for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { int [][] book = new int [height][width]; if (existDfs(board,i,j,book,wordArray,0 )){ return true ; } } } return false ; } }
解码异或后的数组
简单的签到题
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int [] decode(int [] encoded, int first) { int decodedLength = encoded.length + 1 ; int [] decoded = new int [decodedLength]; decoded[0 ] = first; for (int i = 0 ; i < encoded.length; i++) { decoded[i+1 ] = encoded[i] ^ decoded[i]; } return decoded; } }
数组异或操作
两天都是简单的签到题?感觉这道题随便都可以跑到100%
1 2 3 4 5 6 7 8 9 class Solution { public int xorOperation (int n, int start) { int retNum = start; for (int i = 1 ; i < n; i++) { retNum ^= start+i*2 ; } return retNum; } }
螺旋矩阵Ⅰ 开始螺旋矩阵三部曲冲冲冲🐱🏍
经典题目,学C语言的时候看过没写过,写关于矩阵的东西需要找到矩阵变化规律。
网上找的图,就是把四条边动态化(反正这个思路我是想不出来)。矩阵的上下两条边对应,左右两条边对应,一边在加则另一边减,直到两条边重合。
1 2 3 思路: 定义矩阵的四条边 每当遍历完一层这条边就减1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public List<Integer> spiralOrder (int [][] matrix) { int up = 0 ,down = matrix.length - 1 ; int left = 0 ,right = matrix[0 ].length - 1 ; List<Integer> list = new ArrayList<Integer>(); while (true ){ for (int i = left; i <= right; i++) { list.add(matrix[up][i]); } if (++up>down)break ; for (int i = up; i <= down; i++) { list.add(matrix[i][right]); } if (--right < left)break ; for (int i = right; i >= left ; i--) { list.add(matrix[down][i]); } if (--down < up)break ; for (int i = down; i >= up ; i--) { list.add(matrix[i][left]); } if (++left > right)break ; } return list; } }
螺旋矩阵Ⅱ
和螺旋矩阵Ⅰ的思路是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public int [][] generateMatrix(int n) { int left = 0 ,right = n - 1 ; int up = 0 , down = n - 1 ; int [][] matrix = new int [n][n]; int num=1 ; while (true ){ for (int i = up; i <= right; i++) { matrix[up][i] = num++; } if (++up>down)break ; for (int i = up; i <= down ; i++) { matrix[i][right] = num++; } if (--right < left)break ; for (int i = right; i >= left ; i--) { matrix[down][i] = num++; } if (--down < up)break ; for (int i = down; i >= up ; i--) { matrix[i][left] = num++; } if (++left>right)break ; } return matrix; } }
螺旋矩阵Ⅲ
两种思路:
和上面的思路一样,动态模拟四条边
找规律,通过观察可知,每次右移和下移走的步数是奇数,左移和上移走的步数是偶数,所以可以以起始点为中心(上图其实都表示出来了),定义一个正方形,遍历这个正方形的所有坐标,如果坐标范围在矩形内,则符合条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 class Solution { public boolean checkPost (int R,int C,int r0,int c0) { if (r0>=R || r0<0 || c0>=C || c0<0 ) return false ; else return true ; } public int [][] spiralMatrixIII(int R, int C, int r0, int c0) { int [][] arr = new int [R*C][2 ]; int num = 0 ; int max = R>=C?R:C; arr[num][0 ] = r0; arr[num][1 ] = c0; for (int i = 1 ; i <= max*2 ; i+=2 ) { for (int j = 1 ; j <= i; j++) { c0+=1 ; if (checkPost(R,C,r0,c0)){ ++num; arr[num][0 ]=r0; arr[num][1 ]=c0; } } for (int j = 1 ; j <= i; j++) { r0 += 1 ; if (checkPost(R,C,r0,c0)){ ++num ; arr[num][0 ]=r0; arr[num][1 ]=c0; } } for (int j = 1 ; j < i+2 ; j++) { c0 -=1 ; if (checkPost(R,C,r0,c0)){ ++num ; arr[num][0 ]=r0; arr[num][1 ]=c0; } } for (int j = 1 ; j < i+2 ; j++) { r0 -= 1 ; if (checkPost(R,C,r0,c0)){ ++num ; arr[num][0 ]=r0; arr[num][1 ]=c0; } } } return arr; } }