669. 修剪二叉搜索树
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root==null) return null;
//如果当前节点小于low就应该递归右子树并返回右子树符合条件的头节点
if(root.val<low){
TreeNode right=trimBST(root.right,low,high);
return right;
}
if(root.val>high){
TreeNode left=trimBST(root.left,low,high);
return left;
}
//root->left接入符合条件的左孩子
root.left=trimBST(root.left,low,high);
root->right接入符合条件的右孩子
root.right=trimBST(root.right,low,high);
return root;
}
}
108. 将有序数组转换为二叉搜索树
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return traverse(nums,0,nums.length-1);
}
public TreeNode traverse(int[] nums,int left,int right){
//终止条件
if(left>right){
return null;
}
//单层递归
//取数组中间元素
int mid=left+(right-left)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=traverse(nums,left,mid-1);
root.right=traverse(nums,mid+1,right);
return root;
}
}
538. 把二叉搜索树转换为累加树
利用二叉搜索树的中序遍历是升序的改成降序遍历(j将左右调换一下位置即可,先右后左),在在外部维护一个外部累加变量sum,然后把sum赋给BST中的每一个节点即可
class Solution {
public TreeNode convertBST(TreeNode root) {
traverse(root);
return root;
}
int sum=0;
public void traverse(TreeNode root){
if(root==null) return ;
traverse(root.right);
sum+=root.val;
root.val=sum;
traverse(root.left);
}
}
动态规划专题
如果某一问题有很多重叠子问题,使用动态规划是最有效的。动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,
动态规划五部曲
确定dp数组(dp table)以及下标的含义
确定递推公式
dp数组如何初始化
确定遍历顺序
举例推导dp数组
509. 斐波那契数
class Solution {
public int fib(int n) {
//确定dp数组
int[] dp=new int[n+1];
//初始化
if(n<2) return n;
dp[0]=0;
dp[1]=1;
//确定递推公式
for(int i=2;i<n+1;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
70. 爬楼梯、
class Solution {
public int climbStairs(int n) {
int[] dp=new int[n+1];
if(n<=1) return n;
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
746. 使用最小花费爬楼梯
class Solution {
public int minCostClimbingStairs(int[] cost) {
int[] dp=new int[cost.length];
dp[0]=cost[0];
dp[1]=cost[1];
for(int i=2;i<cost.length;i++){
dp[i]=Math.min(dp[i-1],dp[i-2])+cost[i];
}
return Math.min(dp[cost.length - 1], dp[cost.length- 2]);
}
}