代码随想录算法训练营第二十三天 | 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树

75 阅读3分钟

669. 修剪二叉搜索树

链接

文章链接

题目链接

第一想法

由于算法训练营第21天写过对二叉搜索树节点的删除,所以比较好像,总共分为三种情况:

  1. root.val<low 则root应该赋值为foo(root.right)
  2. root.val>high 则root应该赋值为foo(root.left)
  3. 如果root属于[low,hight]之间,则进行对该节点对的左右孩子进行递归.
function trimBST(root: TreeNode | null, low: number, high: number): TreeNode | null {
  const foo:(root: TreeNode | null)=>TreeNode|null=(root: TreeNode | null)=>{
      if(root==null)  return null
      if(root.val<low) return  root=foo(root.right) //这里有删除当前节点的操作
      else if(root.val>high)  return root=foo(root.left)//这里有删除当前节点的操作
      else{
      root.left=foo(root.left)
      root.right=foo(root.right)
      return  root
      }
  }
  return foo(root)
};

看完文章后的想法

文章的想法和我的想法完全一致,所以就不进行代码的展示了,想了解其他语言的代码可以去代码随想录中查看,核心思路也是利用搜索二叉树的性质,所以当root.val小于或大于边界时,可以把root进行相应的替换

思考

这道题不难,唯一要想清楚这三种情况,第一遍写完代码后,对于root=foo(root.right)等前面没有加return ,这是因为我没有想清逻辑关系,如果小于边界了就一定不可能大于边界,所以加上return就结束本层递归

108. 将有序数组转换为二叉搜索树

链接

文章链接

题目链接

第一想法

这道题和用前序和中序构造二叉树的核心思想是一样的,但是这个是搜索二叉树,简单一点,为了让他是平衡的,所以每次取节点都取最中间的节点,这样是可以保证左右子树高度不超过一的

function sortedArrayToBST(nums: number[]): TreeNode | null {
    const foo:(nums: number[])=>TreeNode | null=(nums)=>{
        if(nums.length<=0) return null //终止条件
     let num:number=Math.floor(nums.length/2)//取最中间的节点
     let node=new TreeNode(nums[num])//构建节点
     let left:number[]=nums.slice(0,num)
     let right:number[]=nums.slice(num+1,nums.length)
        node.left=foo(left)//左侧递归
        node.right=foo(right)//右侧递归
        return node
    }
    return foo(nums)
};

看完文章后的想法

文章也是用了和我相同的想法,但是不一样的是我是传的数组而文章用的是左右边界,所以文章中的题解是优于我的题解的,代码如下:

function sortedArrayToBST(nums: number[]): TreeNode | null {
const foo:(nums: number[],left:number,right:number)=>TreeNode | null=(nums,left,right)=>{
    if(left>=right) return null
 let midnumber=Math.floor((left+right)/2)
 let node=new TreeNode(nums[midnumber])
    node.left=foo(nums,left,midnumber)
    node.right=foo(nums,midnumber+1,right)
    return node
}
return foo(nums,0,nums.length)
};

思考

因为之前已经练习过利用中序和前序构造二叉树,所以这道题读完题后就有了一定的思路,所以这道题写出来并不困难.核心思想就是每次取中点,就可以构造出一棵平衡的二叉搜索树.

538. 把二叉搜索树转换为累加树

链接

文章链接

题目链接

第一想法

这道题如果不给是二叉搜索树的话,不会这么好做,利用二叉搜索树的性质,root.right>root>root.left,所以用递归的话,应该按照右中左的顺序,之后再用一个遍历存储和就可以了,代码如下:

function convertBST(root: TreeNode | null): TreeNode | null {
    let num:number=0
    const foo=(root: TreeNode | null)=>{
            if(root==null) return 
            foo(root.right)
            num+=root.val
            root.val=num
            foo(root.left)
    }
    foo(root)
    return root
 };

看完文章后的想法

文章的想法和我的是一致的,所以就不放代码了,核心思想就是搜索二叉树是一个升序的数组,从后向前求累加和,所以就是利用反中序(右中左)进行求解就可以了.

今日总结

今天的三道题不算很难,但是都是比较有意思的,三道题都是利用二叉搜索树的性质解决的,第一道题是修剪,第二道题是利用前序和中序,第三道题是利用搜索二叉树和升序数组的关系进行求解.今天耗时2.5h