二叉树的最大深度

二叉树,所以可以考虑用递归来做。由于根节点已经算过了,所以需要加上1;每次返回都是以递归时的节点作为根节点进行判断的最大深度。还是比较好理解,代码如下:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL) return 0;
int LeftSize=1+maxDepth(root->left);
int RightSize=1+maxDepth(root->right);
return max(LeftSize,RightSize);
}
};

在网上还看到了有人用队列来做,附代码如下:

class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
int res=0;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
++res;
int n=q.size();
for(int i=0;i<n;++i)
{
TreeNode *t=q.front();q.pop();
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
}
return res;
}
};

这个方法也是非常的巧妙!利用队列来存储每一个要处理的节点,处理之前先记一次数res,处理时从队列中拿出来,专门处理这个节点,如果这个节点是子节点,不执行操作;如果不为子节点,在队列中存储它的左右节点,在下一次循环中先取左节点再取右节点进行处理。

验证二叉搜索树

这道题没什么思路,开始想用和上一道题一样的递归的解法,发现不得行。直接看了大神的代码:

// Recursion without inorder traversal
class Solution {
public:
bool isValidBST(TreeNode *root) {
return isValidBST(root, LONG_MIN, LONG_MAX);
}
bool isValidBST(TreeNode *root, long mn, long mx) {
if (!root) return true;
if (root->val <= mn || root->val >= mx) return false;
return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);
}
};

他这样的解法是重载了一个新的isValidBST函数,用自己需要的参数进行判断(还有此等操作??!!)然后利用return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);进行递归判断,而判断语句也写得非常的巧妙if (root->val <= mn || root->val >= mx) return false;。首先每次递归的时候会判断语句中的两个判断条件的一个是否满足条件,就是判断root->left与root进行比较或者将root->right与root进行比较,而另外一个条件则是由于传送了参数LONG_MIN,与LONG_MAX,所以这部分条件是始终满足的。而实现这么巧妙的一个判断语句能分情况的处理条件是和我们传送参数的顺序有关的,比如isValidBST(root->left, mn, root->val)isValidBST(root->right, root->val, mx)两个参数的顺序不一致,所以可以实现这么巧妙的变化。

此外网上还有其他解法:

public class Solution {
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
public int lastVal = Integer.MAX_VALUE;
public boolean firstNode = true;
public boolean isValidBST(TreeNode root) {
// write your code here
if(root == null){
return true;
}
if(!isValidBST(root.left)){
return false;
}
if(!firstNode && lastVal >= root.val){
return false;
}
//此时 root.val>=lastval 是右子树
firstNode = false;
lastVal = root.val;
if(!isValidBST(root.right)){
return false;
}
return true;
}
}

这段代码里是用lastVal来存储目前处理的上一个根节点的值,firstNode来判断现在处理的是左子树还是右子树。这道题还是挺有难度的。

对称二叉树

利用队列,检测左节点的左节点与右节点的右节点、左节点的右节点与右节点的左节点是否相等。循环的条件为队列中有元素,没有元素就代表所有结点都判断完了,返回true;中途如果有不满足判断条件,就直接返回false。值得一提的是,while循环中创建了两个新节点node1与node2,分别存储各自根节点的左或右子节点,看代码就应该比较好理解:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
queue<TreeNode *>q1,q2;
q1.push(root->left);
q2.push(root->right); while(!q1.empty() && !q2.empty())
{
TreeNode *node1=q1.front();
TreeNode *node2=q2.front();
q1.pop();q2.pop();
if((node1==NULL && node2!=NULL) || (node1!=NULL && node2==NULL))
return false;
if(node1!=NULL && node2!=NULL)
{
if(node1->val!=node2->val)
return false;
else
{
q1.push(node1->left);
q2.push(node2->right);
q1.push(node1->right);
q2.push(node2->left);
}
}
}
return true;
}
};

然后,这里再贴出大神的重载函数代码:

class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return isSymmetric(root->left,root->right);
}
bool isSymmetric(TreeNode *left,TreeNode *right){
if(!left && !right) return true;
if((left && !right) || (!left && right) || (left->val!=right->val)) return false;
return isSymmetric(left->left,right->right) && isSymmetric(left->right,right->left);
}
};

二叉树的层次遍历

    /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
//二叉树层次遍历 通过队列BFS广度优先搜索
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*>q;
vector<int> level; //每层结果
int size,i;
TreeNode* p; if(root==NULL) return result;
q.push(root); //入队
while(!q.empty()) {
//队列中有几个元素就依次遍历每个元素的左右结点
level.clear();
size=q.size();
for(i=0; i<size; i++) {
p=q.front(); //队首元素值赋给p
q.pop(); //出队
level.push_back(p->val);
if(p->left) { //依次压入左右结点元素
q.push(p->left);
}
if(p->right) {
q.push(p->right);
}
}
result.push_back(level); //添加每层数据
}
return result;
}
};

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

平衡二叉树的根节点的值为数组中的中间值,即中序遍历时,根结点位于正中间;所以使用二分法,先把有序数组的最中间值设为根结点,然后根结点的左孩子是左半段数组的最中间值,根结点的右孩子是右半段数组的最中间值。依次这样,即可以建立一个平衡二叉搜索树。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return sortedArrayToBST(nums,0,nums.size()-1);
} TreeNode* sortedArrayToBST(vector<int> &nums,int begin ,int end){
if(begin>end)
return NULL;
int mid=(begin+end)/2;
TreeNode* root=new TreeNode(nums[mid]); //根结点,为当前数组的中间值
root->left = sortedArrayToBST(nums , begin , mid - 1);//根结点的左孩子为左半段数组的中间值
root->right = sortedArrayToBST(nums , mid + 1 , end);//根结点的右孩子为右半段数组的中间值
return root;
}
};

LeetCode初级算法(树篇)的更多相关文章

  1. LeetCode初级算法--树01:二叉树的最大深度

    LeetCode初级算法--树01:二叉树的最大深度 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...

  2. LeetCode初级算法--树02:验证二叉搜索树

    LeetCode初级算法--树02:验证二叉搜索树 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

  3. LeetCode初级算法(其他篇)

    目录 缺失数字 位1的个数 颠倒二进制位 有效的括号 汉明距离 帕斯卡三角形 缺失数字 最初的想法是将0到n全部加起来,再减去输入的数字之和,那么差如果非零的话就是我们所需要的数字.但是一想,可能会发 ...

  4. Leetcode初级算法(链表篇)

    删除链表的倒数第N个节点 感觉自己对于链表的知识还是了解的不够深入,所以没有想到用双指针进行操作.我的想法是这样的,首先计算整个链表的长度,然后遍历到长度减去n的节点处,执行删除操作. 自己的代码: ...

  5. Leetcode初级算法(字符串篇)

    目录 反转字符串 颠倒整数 字符串中的第一个唯一字符 有效的字母异位词 验证回文字符串 实现strStr() 数数并说 最长公共前缀 字符串转整数(atoi) 反转字符串 和vector同样的进行sw ...

  6. LeetCode初级算法(数组)解答

    这里记录了LeetCode初级算法中数组的一些题目: 加一 本来想先转成整数,加1后再转回去:耽美想到测试的例子考虑到了这个方法的笨重,所以int类型超了最大范围65536,导致程序出错. class ...

  7. 【LeetCode算法】LeetCode初级算法——字符串

      在LeetCode初级算法的字符串专题中,共给出了九道题目,分别为:反转字符串,整数反转,字符串中的第一个唯一字符,有效的字母异位词,验证回文字符串,字符串转换整数,实现strStr(),报数,最 ...

  8. LeetCode初级算法之数组:48 旋转图像

    旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...

  9. LeetCode初级算法的Python实现--排序和搜索、设计问题、数学及其他

    LeetCode初级算法的Python实现--排序和搜索.设计问题.数学及其他 1.排序和搜索 class Solution(object): # 合并两个有序数组 def merge(self, n ...

随机推荐

  1. 浅谈vue路由原理

    Vue的路由实现:hash模式 和 history模式 hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取: 特点:hash虽然在UR ...

  2. 第一个 IronPython 的 ASP.NET 程序

    今天试验了在 Visual Studio 中集成使用 IronPython,记录如下. 首先,下载一个 IronPython 1.0 的 binary,解压后,将目录路径 配置到环境变量 Path 中 ...

  3. bzoj 3730 震波 —— 动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3730 建点分树,每个点记两个树状数组,存它作为重心管辖的范围内,所有点到它的距离情况和到它在 ...

  4. Poj1163 The Triangle(动态规划求最大权值的路径)

    一.Description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a pro ...

  5. 项目一:第五天 1、区域数据(pinyin4j-简码,城市编码) 2、Web层代码重构(model对象,分页代码提取) 3、区域分页查询 3、分区添加功能 4、定区管理管理-添加,分页

    Service: /** * @Description: 1.保存定区  2.让分区关联定区 * 对象三种状态 1.持久态(被session管理对象-一级缓存中有对象) 2.托管态(有OID标识,数据 ...

  6. eos命令

    ps -ef|grep javakill -9 端口号cd /opt/sudytrue>nohup.outnohup eos7.5/startServer.sh &

  7. C# 开发网页的打印版

    在项目中,有一个需求时是需要打印产品页面.但是打印出来的版本和网页上的版本不太一致,有些图片不需要,网页上以tab选项卡显示的内容,都需要在打印页面中看到..等等 CSS针对这种需求,引入了一个@me ...

  8. 项目中缺少org.wltea.ik-analyzer如何解决?

    IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本.最初,它是以开源项目Luence为应用主体 ...

  9. 又见GCD (HDU 2504)

    这个题真的很水,但我竟然连错,在此警醒自己!!! 写代码改了东边,忘了西边,“认真”这两个字又被我吃了,打脸啪啪啪啪. #include<iostream> using namespace ...

  10. CocoaPods常用操作命令

    查看镜像: gem sources -l 删除镜像 gem sources --remove https://rubygems.org/ 添加镜像 gem sources -a https://gem ...