654.最大二叉树
题目链接:654.最大二叉树
文档讲解:代码随想录/最大二叉树
视频讲解:视频讲解-最大二叉树
状态:已完成(1遍)
解题过程
看到题目的第一想法
我的思路是每次要在当前数组中取出最大的数字,将其赋值给节点,然后将左侧和右侧的数组部分分给左右子节点,依次递归下去。
手搓代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var constructMaximumBinaryTree = function(nums) {
const maxNode = function(newNum){
if(newNum.length == 0)return null;
let maxNum = -1,index = -1;
for(let i = 0;i<newNum.length;i++){//找出最大值
if(newNum[i]>maxNum){
maxNum = newNum[i];
index = i;//最大值在数组里的索引
}
}
let nd = new TreeNode(maxNum);//赋予当前节点值
nd.left = maxNode(newNum.slice(0,index));
nd.right = maxNode(newNum.slice(index+1));
return nd;
}
return maxNode(nums);
};
运行提交都没有问题,不过用时排在垫底,差点超时。
看完代码随想录之后的想法
这题用递归法的思路是没有问题的,只是在速度上来说,每次构造新数组比较慢,而每次只传入左右两个坐标节点则会更迅速。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var constructMaximumBinaryTree = function(nums) {
const BuildTree = (arr, left, right) => {
if (left > right)
return null;
let maxValue = -1;
let maxIndex = -1;
for (let i = left; i <= right; ++i) {
if (arr[i] > maxValue) {
maxValue = arr[i];
maxIndex = i;
}
}
let root = new TreeNode(maxValue);
root.left = BuildTree(arr, left, maxIndex - 1);
root.right = BuildTree(arr, maxIndex + 1, right);
return root;
}
let root = BuildTree(nums, 0, nums.length - 1);
return root;
};
总结
这题认识到了提高运行速度的一种方法,将构造新数组改为传递左右两端点坐标。
617.合并二叉树
题目链接:617.合并二叉树
文档讲解:代码随想录/合并二叉树
视频讲解:视频讲解-合并二叉树
状态:已完成(1遍)
解题过程
看到题目的第一想法
这题我第一想法是当前新节点的值等于两个节点的值相加,如果原节点存在,则加值,反之则加0;递归的时候对传入参数要进行判断,如果node1和node1.left都存在,才传入。
手搓代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root1
* @param {TreeNode} root2
* @return {TreeNode}
*/
var mergeTrees = function(root1, root2) {
const mergeTwo = function(node1,node2){
if(node1 == null&&node2 == null)return null;
let newNode = new TreeNode();
newNode.val = (node1?node1.val:0)+(node2?node2.val:0);//如果存在,则取val;如果不存在,则取0
newNode.left = mergeTwo(node1 && node1.left, node2 && node2.left);//递归之前先判断,如果node1和node1.left都存在,才传入下一层递归
newNode.right = mergeTwo(node1 && node1.right, node2 && node2.right);
return newNode;
}
return mergeTwo(root1, root2);
};
提交没有问题。
看完代码随想录之后的想法
开头的处理确实让我没想到,如果其中一个没有,直接输出另一个,就算另一个也没有,那就直接为null,也很省力。比我自己的在后面苦苦判断确实省事多了。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root1
* @param {TreeNode} root2
* @return {TreeNode}
*/
var mergeTrees = function (root1, root2) {
const preOrder = (root1, root2) => {
if (!root1)
return root2
if (!root2)
return root1;
root1.val += root2.val;
root1.left = preOrder(root1.left, root2.left);
root1.right = preOrder(root1.right, root2.right);
return root1;
}
return preOrder(root1, root2);
};
总结
这道题要求同时操作两个二叉树,没接触过但也不复杂,只要每次递归传参的时候传两个就可以。
700.二叉搜索树中的搜索
题目链接:700.二叉搜索树中的搜索
文档讲解:代码随想录/二叉搜索树中的搜索
视频讲解:视频讲解-二叉搜索树中的搜索
状态:已完成(1遍)
解题过程
看到题目的第一想法
搜索树的规律就是左子结点比父节点小,右子节点比父节点大。所以我直接在单层递归的处理中进行判断,将当前节点值和目标值进行比较,如果当前值更大,就往左子结点递归,反之往右子节点递归。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} val
* @return {TreeNode}
*/
var searchBST = function(root, val) {
const findNode = function(node){
if(node == null)return null;
if(node.val == val){
return node;
}else if(node.val > val){
return findNode(node.left);
}else if(node.val < val){
return findNode(node.right);
}
}
return findNode(root);
};
这里值得注意的是每层递归都得写return。
看完代码随想录之后的想法
确实第一句有简便写法。而且甚至都不用再写个函数。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} val
* @return {TreeNode}
*/
var searchBST = function(root, val) {
if (!root || root.val === val) {
return root;
}
if (root.val > val)
return searchBST(root.left, val);
if (root.val < val)
return searchBST(root.right, val);
};
总结
二叉搜索树是位好二叉树哈哈。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树
98.验证二叉搜索树
题目链接:98.验证二叉搜索树
文档讲解:代码随想录/验证二叉搜索树
视频讲解:视频讲解-验证二叉搜索树
状态:已完成(1遍)
解题过程
看到题目的第一想法
这道题我的想法是每一层都判断一下是不是搜索二叉树,然后将结果返回给上一级父节点。
手搓代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function(root) {
const see = function(node){
if(node == null)return true;//空的返回true
let leftNode = see(node.left);//左子结点递归
if(node.left&&node.left.val>=node.val)return false;//如果左子结点存在且值大于父节点值,false
let rightNode = see(node.right);
if(node.right&&node.right.val<=node.val)return false;//如果右子结点存在且值小于父节点值,false
return leftNode && rightNode//如果左右子节点都守规矩,那么返回左右子节点是否是搜索二叉树
}
return see(root);
};
运行没有问题,但提交只有77/85。
debug了很久发现问题应该出在,我无法判断子节点里是不是所有值都大于或小于父节点,也就是有可能出现左子结点的右子节点比本节点值还要大。所以我想着将一个当前节点的最大最小值记录下来,与父节点比较。
看完代码随想录之后的想法
看来我犯的错是经典的错误哈哈。这题借用数组的思路十分巧妙,但是讲解的递归法有点难以理解。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var isValidBST = function (root) {
let arr = [];
const buildArr = (root) => {
if (root) {
buildArr(root.left);
arr.push(root.val);
buildArr(root.right);
}
}
buildArr(root);
for (let i = 1; i < arr.length; ++i) {
if (arr[i] <= arr[i - 1])
return false;
}
return true;
};
总结
既然搜索二叉树是一个有序二叉树,那么将其转换为数组,再来比较数组是否是一个递增数组就好。