剑指 Offer 12. 矩阵中的路径、13. 机器人的运动范围、34. 二叉树中和为某一值的路径、36. 二叉搜索树与双向链表、54. 二叉搜索树的第k大节点
题目描述:
[12]
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
[13]
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
[34]
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
[36]
[54]
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
考察重点:
第12题首先遍历数组找到起始位置,再使用dfs搜索符合题意的路径
第13题使用mark数组记录当前位置是否被访问过,定义isLegal判断x,y是否越界是否被访问过并且是否符合题意,最后向右向下遍历矩阵:dfs(右)+dfs(下)+1
第34题标准递归回溯找寻所有情况,依次深度遍历整个树即可。
第36题引入一个新节点head记录递归的上一节点,和当前节点root相互指向即可。最后需要用recHead记录头结点并和尾结点相互指向。
第54题以“先右再中再左”的顺序遍历树,遍历到“中”时–k,当k为0时,说明当前节点为第k大节点。
第12题
int[][] way = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};public boolean dfs(char[][] board, int nowPos, String target, int x, int y){if(nowPos >= target.length())return true;char targetWord = target.charAt(nowPos);for(int i = 0;i < 4;i ++){char nowWord = board[x][y];board[x][y] = '0';x += way[i][0];y += way[i][1];if(x >= 0 && x < board.length && y >= 0 && y < board[0].length && nowWord == targetWord && dfs(board, nowPos + 1, target, x, y))return true;x -= way[i][0];y -= way[i][1];board[x][y] = nowWord;}return false;}public boolean exist(char[][] board, String word) {char mark = word.charAt(0);for(int i = 0;i < board.length;i ++)for(int j = 0;j < board[0].length;j ++){if(mark == board[i][j]){if(dfs(board, 0, word, i, j) || (word.length() == 1))return true;}}return false;}
第13题
int[][] mark;public boolean isLegel(int x, int y, int k){if(x >= mark.length || x < 0 || y >= mark[0].length || y < 0 || mark[x][y] == 1)return false;return k >= x % 10 + x / 10 + y % 10 + y / 10;}public int dfs(int x, int y, int k){if(!isLegel(x, y, k))return 0;mark[x][y] = 1;return dfs(x + 1, y, k) + dfs(x, y + 1, k) + 1;}public int movingCount(int m, int n, int k) {mark = new int[m][n];return dfs(0, 0, k);}
第34题
List<List<Integer>> res;public int dfs(TreeNode root, List<Integer> list, int target){if(root.right == null && root.left == null && target == 0){res.add(new ArrayList<Integer>(){{addAll(list);}});return 0;}if(root.right != null){list.add(root.right.val);dfs(root.right, list, target - root.right.val);list.remove(list.size()-1);}if(root.left != null){list.add(root.left.val);dfs(root.left, list, target - root.left.val);list.remove(list.size()-1);}return 0;}public List<List<Integer>> pathSum(TreeNode root, int target) {res = new ArrayList<>();if(root == null)return res;dfs(root, new ArrayList<Integer>(){{add(root.val);}}, target - root.val);return res;}
第36题
Node head = new Node();Node recHead = head;public void dfs(Node root){if(root.left != null)dfs(root.left);head.right = root;root.left = head;head = head.right;if(root.right != null)dfs(root.right);}public Node treeToDoublyList(Node root) {if(root == null){return null;}dfs(root);head.right = recHead.right;recHead.right.left = head;return recHead.right;}
第54题
int rec;public int dfs(TreeNode root){if(root == null)return 0;int a = dfs(root.right);if(--rec == 0){return root.val;}int b = dfs(root.left);return Math.max(a, b);}public int kthLargest(TreeNode root, int k) {rec = k;return dfs(root);}