一、二叉搜索树的范围和
题目
思路
考虑3种情况
(1)当前结点的值在区间[low,high]
(2)当前结点的值小于low
(3)当前结点的值大于high
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int rangeSumBST(TreeNode root, int low, int high) {
int res=0;
if(root==null)
{
return res;
}
//cur大于等于low,小于等于high,res+=cur,向右子树走
if(root.val>=low && root.val<=high)
{
res+=root.val;
if(root.val==low)
res+=rangeSumBST(root.right,low,high);
else
{
res+=rangeSumBST(root.left,low,high);
res+=rangeSumBST(root.right,low,high);
}
}
//小于low,则舍弃左子树,往右子树走
else if(root.val<low)
{
res+=rangeSumBST(root.right,low,high);
}
//大于high,往左子树走
else
{
res+=rangeSumBST(root.left,low,high);
}
return res;
}
}
二、二叉树的最大深度
题目
思路
(1)如果当前结点为null,返回0
(2)如果当前结点不为null,检查左右子树,返回最高的子树的值
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
//如果当前结点为空,返回0
if(root==null)
return 0;
//否则查看左右子树,看谁更高
int l=0,r=0;
l=1+maxDepth(root.left);
r=1+maxDepth(root.right);
return Math.max(l,r);
}
}
三、剑指 Offer 55 - II. 平衡二叉树
题目
思路
与上一题求二叉树的最大深度有关,因为这题求是否是平衡二叉树,因此我们可以在求最大深度时,判断左右子树的高度差是否不超过1。如果超过,则返回-1,表示子树已经不满足平衡二叉树的条件。
depth(root)函数
:
1、当结点root
左右子树的高度差小于等于1
,则返回当前子树的深度
2、当结点root
左右子树高度差大于1
,则不满足平衡二叉树,返回-1
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return depth(root)!=-1;
}
public int depth(TreeNode root)
{
if(root==null)
return 0;
//记录左右子树长度
int l,r;
l=depth(root.left);
if(l==-1)
return -1;
r=depth(root.right);
if(r==-1)
return -1;
return Math.abs(l-r)<=1?1+Math.max(l,r):-1;
}
}
四、剑指 Offer 12. 矩阵中的路径
题目
思路
1、由于单元格字母不能重复访问,因此创建一个对应的记录单元格是否访问的二维数组visited
,visited[i][j]=1
表示已经访问过该单元,visited[i][j]=0
则表示该单元格尚未访问
2、由于不知道是从board矩阵
的哪个位置出发,因此我们循环遍历,对每一个位置都进行尝试,当循环每一个位置都没有找到符合的路径的话,就返回false
,只要在某一个位置找到了,则立即返回true
结束
3、findPath函数
用来寻找到达字符chArr[cur]
的路径,找到到达当前字符的路径后,再从当前字符依照上右下左
的规律寻找到达下一个字符的路径,如果有一个方向合适,则对这个方向向下进行递归。如果没有任何一个方向合适,则回溯到上一个字符,再寻求另一条路径到达字符chArr[cur]
,若没有,则继续回溯到上一个字符,直到找到一条合适的路径,或退出findPath函数
进入到主函数中选取新的起始字符位置
例如:
board={{'C','A','A'},{'A','A','A'},{'B','C','D'}}
word="AAB"
运行过程如下:
4、在回溯
的过程中要把当前的单元格的访问位visited[i][j]
置为0,以免后面从其它位置进行向下递归时受到影响;同时cur--
,因为需要重新从这个字符寻求其它路径到达下一个字符
代码
class Solution {
public boolean exist(char[][] board, String word) {
int m=board.length;
int n=board[0].length;
char chArr[]=word.toCharArray();
//记录单元格是否已经访问,0表示未访问,1表示已访问
int visited[][]=new int[m][n];
//记录当前需要匹配的字符的序号
int cur=0;
//开始位置不清楚在哪,因此对每个位置进行尝试
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(findPath(board,i,j,chArr,cur,visited))
return true;
}
}
return false;
}
/**
*
* @param board 二维网格
* @param row 当前所在的行
* @param column 当前所在的列
* @param chArr 待查找的字符串转换的数组
* @param cur 当前需要查找的字符序号
* @param visited 记录单元格是否已访问
* @return
*/
public boolean findPath(char board[][],int row,int column,char chArr[],int cur,int visited[][])
{
//如果路径能到达最后一个字符,说明存在此路径
if(cur==chArr.length)
return true;
boolean res=false;
//如果当前位置合法,当前字符对应相等且未被访问过,则说明该位置是可通的,从该位置进行向下递归
if(row>=0 && row<board.length && column>=0 && column<board[0].length &&
board[row][column]==chArr[cur] && visited[row][column]!=1)
{
visited[row][column]=1;
cur++;
//递归顺序:上右下左
//只要有其中一条路径可走,则会进入到那条路径向下递归
//没有可走的路径,则回溯
res=(findPath(board, row-1, column, chArr, cur, visited)
|| findPath(board, row, column+1, chArr, cur, visited)
|| findPath(board, row+1, column, chArr, cur, visited)
|| findPath(board, row, column-1, chArr, cur, visited));
//回溯
if(res==false)
{
cur--;
visited[row][column]=0;
}
}
return res;
}
}