关于《剑指offer》的66道编程题的总结(五)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43949535/article/details/100640227

注:2019年9月8日21:57:16 这部分主要是解决与二叉树相关的问题

(第四十一题)重建二叉树

2019年9月8日21:58:43
题目链接:
https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月8日21:04:15                                  
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月8日21:55:55                
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
int main()
{
	Solution solution;	
	
	vector<int>pre({ 1,2,4,7,3,5,6,8 });
	vector<int>vin({ 4,7,2,1,5,3,8,6 });


	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述

(第四十二题)从上往下打印二叉树

2019年9月9日00:30:22
题目链接:
https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13&tqId=11175&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月8日21:04:15                                  
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月8日21:55:55                
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的层序遍历:1 2 3 4 5 6 7 8
*/
class Solution {
public:
	vector<int> PrintFromTopToBottom(TreeNode* root)
	{
		vector<int>myvec;
		if (root == nullptr)
		{
			return myvec;
		}

		TreeNode* p = root;
		queue<TreeNode*>myque;//存放节点,出队列的时候 访问气质

		myque.push(p);//先把根节点入队
		while (!myque.empty())
		{
			TreeNode* temp_p = myque.front();
			myque.pop();
			if (temp_p->left != nullptr)
			{
				myque.push(temp_p->left);
			}
			if (temp_p->right!=nullptr)
			{
				myque.push(temp_p->right);
			}
			myvec.push_back(temp_p->val);
		}
		return myvec;
	}
};
int main()
{
	Solution1 solution1;	
	Solution solution;
	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
	
	//先 中序建树,上一个题目的
	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);
	
	for (int val : solution.PrintFromTopToBottom(this_new_tree))//本题主要是 层次遍历一个二叉树
	{
		cout << val << " ";//层次遍历二叉树
	}
	cout << endl;
	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
上一个题目单单是建树,尚未测试:
在这里插入图片描述
在这里插入图片描述
2019年9月9日00:34:35

(第四十三题)二叉树的深度

2019年9月9日00:45:28
题目链接:
https://www.nowcoder.com/practice/435fb86331474282a3499955f0a41e8b?tpId=13&tqId=11191&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日00:37:30                                 
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日00:46:28             
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的层序遍历:1 2 3 4 5 6 7 8
*/
class Solution2 {
public:
	vector<int> PrintFromTopToBottom(TreeNode* root)
	{
		vector<int>myvec;
		if (root == nullptr)
		{
			return myvec;
		}

		TreeNode* p = root;
		queue<TreeNode*>myque;//存放节点,出队列的时候 访问气质

		myque.push(p);//先把根节点入队
		while (!myque.empty())
		{
			TreeNode* temp_p = myque.front();
			myque.pop();
			if (temp_p->left != nullptr)
			{
				myque.push(temp_p->left);
			}
			if (temp_p->right!=nullptr)
			{
				myque.push(temp_p->right);
			}
			myvec.push_back(temp_p->val);
		}
		return myvec;
	}
};
class Solution {
public:
	int TreeDepth(TreeNode* pRoot)
	{
		if (pRoot == nullptr)
			return 0;

		//二叉树的深度等于 左右子树的深度的最大值+1
		return max(TreeDepth(pRoot->left), TreeDepth(pRoot->right)) + 1;
	}
};
int main()
{
	Solution1 solution1;	
	Solution2 solution2;
	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	for (int val : solution2.PrintFromTopToBottom(this_new_tree))//本题主要是 层次遍历一个二叉树
	{
		cout << val << " ";//层次遍历二叉树
	}
	cout << endl;
	Solution solution3;
	cout << solution3.TreeDepth(this_new_tree) << endl;
	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
本节代码 囊括了上面两题的代码。
测试如下:
在这里插入图片描述
2019年9月9日00:47:59

(第四十四题)二叉树的镜像

2019年9月9日01:05:38
题目链接:
https://www.nowcoder.com/practice/564f4c26aa584921bc75623e48ca3011?tpId=13&tqId=11171&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:包括了上面3个题的代码

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日00:37:30                                 
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间:              
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的层序遍历:1 2 3 4 5 6 7 8
*/
class Solution2 {
public:
	vector<int> PrintFromTopToBottom(TreeNode* root)
	{
		vector<int>myvec;
		if (root == nullptr)
		{
			return myvec;
		}

		TreeNode* p = root;
		queue<TreeNode*>myque;//存放节点,出队列的时候 访问气质

		myque.push(p);//先把根节点入队
		while (!myque.empty())
		{
			TreeNode* temp_p = myque.front();
			myque.pop();
			if (temp_p->left != nullptr)
			{
				myque.push(temp_p->left);
			}
			if (temp_p->right!=nullptr)
			{
				myque.push(temp_p->right);
			}
			myvec.push_back(temp_p->val);
		}
		return myvec;
	}
};
class Solution3 {//主要是做 二叉树的深度
public:
	int TreeDepth(TreeNode* pRoot)
	{
		if (pRoot == nullptr)
			return 0;

		//二叉树的深度等于 左右子树的深度的最大值+1
		return max(TreeDepth(pRoot->left), TreeDepth(pRoot->right)) + 1;
	}
};
class Solution {//主要是做 二叉树的镜像反转
public://镜像反转,反转之后的新二叉树的 中序遍历和旧的 是逆序相反的
	void Mirror(TreeNode* pRoot) 
	{
		if (pRoot == nullptr)
			return;
		swap(pRoot->left, pRoot->right);
		Mirror(pRoot->left);
		Mirror(pRoot->right);
	}
};
int main()
{
	Solution1 solution1;	
	Solution2 solution2;
	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	for (int val : solution2.PrintFromTopToBottom(this_new_tree))//本题主要是 层次遍历一个二叉树
	{
		cout << val << " ";//层次遍历二叉树
	}
	cout << endl;
	Solution3 solution3;
	cout << solution3.TreeDepth(this_new_tree) << endl;//主要是做 二叉树的深度
	Solution solution4;
	solution4.Mirror(this_new_tree);//反转这个树
	
	//下面主要是测试一下 树反转了没
	for (int val : solution2.PrintFromTopToBottom(this_new_tree))
	{
		cout << val << " ";//层次遍历二叉树
	}
	cout << endl;
	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日01:07:42

(第四十五题)按之字形顺序打印二叉树

2019年9月9日01:42:31
题目链接:
https://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0?tpId=13&tqId=11212&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日01:11:03                                 
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日01:43:11             
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的之字形遍历:1 3 2 4 5 6 8 7
*/

class Solution {
public:
	vector<vector<int>> Print(TreeNode* pRoot)
	{
		vector<vector<int>>result_vec;
		if (pRoot == nullptr)
			return result_vec;

		//第一行 从左到右
		//第二行 从右到左
		//第三行 从左到右
		// ---     ---
		queue<TreeNode*>myque;//做层次遍历用的
		vector<int>myvec;
		myque.push(pRoot);//第一行 从左到右
		int k = 1;
		while (!myque.empty())//一次处理一行
		{
			int cursize = myque.size();
			for (int i = 0; i < cursize; ++i)
			{
				TreeNode* p = myque.front();
				myque.pop();
				myvec.push_back(p->val);

				if (p->left != nullptr)
					myque.push(p->left);
				if (p->right != nullptr)
					myque.push(p->right);
			}
			//一行的数据全部入了
			if (k % 2 == 0)
			{
				reverse(myvec.begin(), myvec.end());//偶数行需要进行反转
			}
			result_vec.push_back(myvec);
			myvec.clear();
			k++;
		}

		return result_vec;
	}

};

int main()
{
	Solution1 solution1;	
	Solution solution2;
	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	vector<vector<int>>myvec = solution2.Print(this_new_tree);
	for (vector<int>&val : myvec)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}

	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日01:44:29

(第四十六题)把二叉树打印成多行

2019年9月9日01:52:53
题目链接:
https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=13&tqId=11213&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:这题和上面一个题 非常类似

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日01:46:10                                 
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日01:53:41            
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的之字形遍历:1 3 2 4 5 6 8 7
*/

class Solution2 {//按照之字形顺序打印 二叉树
public:
	vector<vector<int>> Print(TreeNode* pRoot)
	{
		vector<vector<int>>result_vec;
		if (pRoot == nullptr)
			return result_vec;

		//第一行 从左到右
		//第二行 从右到左
		//第三行 从左到右
		// ---     ---
		queue<TreeNode*>myque;//做层次遍历用的
		vector<int>myvec;
		myque.push(pRoot);//第一行 从左到右
		int k = 1;
		while (!myque.empty())//一次处理一行
		{
			int cursize = myque.size();
			for (int i = 0; i < cursize; ++i)
			{
				TreeNode* p = myque.front();
				myque.pop();
				myvec.push_back(p->val);

				if (p->left != nullptr)
					myque.push(p->left);
				if (p->right != nullptr)
					myque.push(p->right);
			}
			//一行的数据全部入了
			if (k % 2 == 0)
			{
				reverse(myvec.begin(), myvec.end());//偶数行需要进行反转
			}
			result_vec.push_back(myvec);
			myvec.clear();
			k++;
		}

		return result_vec;
	}

};
class Solution {//把二叉树 打印成多行
public:
	vector<vector<int>> Print(TreeNode* pRoot) 
	{
		vector<vector<int>>result_vec;
		if (pRoot == nullptr)
			return result_vec;

		queue<TreeNode*>myque;//做层次遍历用的
		vector<int>myvec;
		myque.push(pRoot);//处理第一行 

		while (!myque.empty())//一次处理一行
		{
			int cursize = myque.size();
			for (int i = 0; i < cursize; ++i)
			{
				TreeNode* p = myque.front();
				myque.pop();
				myvec.push_back(p->val);

				if (p->left != nullptr)
					myque.push(p->left);
				if (p->right != nullptr)
					myque.push(p->right);
			}
			//一行的数据全部入了
		
			result_vec.push_back(myvec);
			myvec.clear();
		}
		return result_vec;
	}
};
int main()
{
	Solution1 solution1;	
	Solution2 solution2;
	Solution solution3;
	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	vector<vector<int>>myvec = solution2.Print(this_new_tree);//按照之字形顺序打印 二叉树
	for (vector<int>&val : myvec)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}
	cout << "**************" << endl;
	vector<vector<int>>myvec1 = solution3.Print(this_new_tree);
	for (vector<int>& val : myvec1)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}
	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日01:55:05

(第四十七题)对称的二叉树

2019年9月9日02:36:58
题目链接:
https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=13&tqId=11211&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日01:53:41                             
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日02:38:08           
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的之字形遍历:1 3 2 4 5 6 8 7
*/

class Solution2 {//按照之字形顺序打印 二叉树
public:
	vector<vector<int>> Print(TreeNode* pRoot)
	{
		vector<vector<int>>result_vec;
		if (pRoot == nullptr)
			return result_vec;

		//第一行 从左到右
		//第二行 从右到左
		//第三行 从左到右
		// ---     ---
		queue<TreeNode*>myque;//做层次遍历用的
		vector<int>myvec;
		myque.push(pRoot);//第一行 从左到右
		int k = 1;
		while (!myque.empty())//一次处理一行
		{
			int cursize = myque.size();
			for (int i = 0; i < cursize; ++i)
			{
				TreeNode* p = myque.front();
				myque.pop();
				myvec.push_back(p->val);

				if (p->left != nullptr)
					myque.push(p->left);
				if (p->right != nullptr)
					myque.push(p->right);
			}
			//一行的数据全部入了
			if (k % 2 == 0)
			{
				reverse(myvec.begin(), myvec.end());//偶数行需要进行反转
			}
			result_vec.push_back(myvec);
			myvec.clear();
			k++;
		}

		return result_vec;
	}

};
class Solution {//判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
public:
	static bool compare_tree(TreeNode* left, TreeNode* right)
	{
		if (left == nullptr)
			return right == nullptr;//看看右是不是空
		if (right == nullptr)
			return false;//左边不空,右边空
		if (left->val != right->val)
			return false;//两边不空,值不等

		//接下来看 这两个孩子节点的左的左和右的右、左的右和右的左进行对比
		return compare_tree(left->left, right->right) && compare_tree(left->right, right->left);
	}
	bool isSymmetrical(TreeNode* pRoot)
	{
		if (pRoot == nullptr)
			return true;//递归结束的边界

		return compare_tree(pRoot->left, pRoot->right);
	}

};
int main()
{
	Solution1 solution1;	
	Solution2 solution2;

	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	vector<vector<int>>myvec = solution2.Print(this_new_tree);//按照之字形顺序打印 二叉树
	for (vector<int>&val : myvec)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}
	Solution solution;
	if (solution.isSymmetrical(this_new_tree) == false)
		cout << "不是对称的树" << endl;

	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日02:39:11
(连写了 七个题,身体实在是扛不住了。好累)
我这两天刷了剑指offer 有45道题,真心地体会到 当年上大学时,课堂的那句话:程序设计=算法+数据结构。

(第四十八题)二叉树中和为某一值的路径

2019年9月9日14:39:35
题目链接:
https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca?tpId=13&tqId=11177&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:代码包含了1. 根据先中序,建树。2.按照之字形顺序打印 二叉树。3 二叉树中和为某一值的路径。

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日01:46:10                                 
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日14:44:33            
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <map>
#include <algorithm>
#include <iomanip>
using namespace std;


//Definition for binary tree
struct TreeNode {
	 int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution1 {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
	{
		int size1 = pre.size();
		int size2 = vin.size();

		if (size1 == 0 || size2 == 0)//递归终止条件
		{
			return nullptr;
		}

		int root_val = pre[0];
		TreeNode* root = new TreeNode(root_val);//先序的第一个值 为root根节点

		//分别定义左右子序列的 先序 中序序列
		vector<int>pre_left, pre_right, vin_left, vin_right;

		//第一步:求出这个树的根节点root_val在中序序列中的位置
		vector<int>::iterator it_root = vin.begin();
		int k = 0;
		for (; it_root != vin.end(); ++it_root)
		{
			if (*it_root == root_val)
			{
				break;
			}
			k++;//k保存的是左子树的中序序列的个数
			//此时的it_root 正是这个树的根root_val在中序序列中的位置
		}
		//第二步:把左子树的中序序列和先序序列给求出来
		for (int i = 0; i < k; ++i)
		{
			pre_left.push_back(pre[i + 1]);//把先序序列中的左子树的部分放到左子树先序序列里面
			vin_left.push_back(vin[i]);//把中序序列中的左子树的部分放到左子树中序序列里面
		}
		//第三步:把右子树的中序序列和先序序列给求出来
		for (int i = k + 1; i < size1; ++i)//别把根节点给插进去了
		{
			pre_right.push_back(pre[i]);//把先序序列中的右子树的部分放到右子树先序序列里面
			vin_right.push_back(vin[i]);//把中序序列中的右子树的部分放到右子树中序序列里面
		}
		//第四步:递归调用 建树
		root->left = reConstructBinaryTree(pre_left, vin_left);//建立左子树
		root->right = reConstructBinaryTree(pre_right, vin_right);//建立右子树

		return root;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
所以下面打印的之字形遍历:1 3 2 4 5 6 8 7
*/

class Solution2 {//按照之字形顺序打印 二叉树
public:
	vector<vector<int>> Print(TreeNode* pRoot)
	{
		vector<vector<int>>result_vec;
		if (pRoot == nullptr)
			return result_vec;

		//第一行 从左到右
		//第二行 从右到左
		//第三行 从左到右
		// ---     ---
		queue<TreeNode*>myque;//做层次遍历用的
		vector<int>myvec;
		myque.push(pRoot);//第一行 从左到右
		int k = 1;
		while (!myque.empty())//一次处理一行
		{
			int cursize = myque.size();
			for (int i = 0; i < cursize; ++i)
			{
				TreeNode* p = myque.front();
				myque.pop();
				myvec.push_back(p->val);

				if (p->left != nullptr)
					myque.push(p->left);
				if (p->right != nullptr)
					myque.push(p->right);
			}
			//一行的数据全部入了
			if (k % 2 == 0)
			{
				reverse(myvec.begin(), myvec.end());//偶数行需要进行反转
			}
			result_vec.push_back(myvec);
			myvec.clear();
			k++;
		}

		return result_vec;
	}

};
class Solution3 {//判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
public:
	static bool compare_tree(TreeNode* left, TreeNode* right)
	{
		if (left == nullptr)
			return right == nullptr;//看看右是不是空
		if (right == nullptr)
			return false;//左边不空,右边空
		if (left->val != right->val)
			return false;//两边不空,值不等

		//接下来看 这两个孩子节点的左的左和右的右、左的右和右的左进行对比
		return compare_tree(left->left, right->right) && compare_tree(left->right, right->left);
	}
	bool isSymmetrical(TreeNode* pRoot)
	{
		if (pRoot == nullptr)
			return true;//递归结束的边界

		return compare_tree(pRoot->left, pRoot->right);
	}

};
/*
路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

递归先序遍历树, 把结点加入路径。
若该结点是叶子结点则比较当前路径和是否等于期待和。
弹出结点,每一轮递归返回到父结点时,当前路径也应该回退一个结点
*/
class Solution {//二叉树中和为某一值的路径
public:
	void myfind(TreeNode* root, int expectNumber, vector<vector<int>>& result,vector<int>&curpath)
	{
		if (root == nullptr)
			return;
		curpath.push_back(root->val);//当前节点入路径
		
		//若是本节点为叶子节点,且本路径刚好是 期待路径
		//这个地方,最好是把值的判断放在前面,值若是不合适了,就没必要接着往下走了
		if (expectNumber - root->val == 0 && root->left == nullptr && root->right == nullptr)
		{
			result.push_back(curpath);
		}
		else
		{
			if (root->left != nullptr)//左孩子不为空
			{
				myfind(root->left, expectNumber - root->val, result, curpath);
			}
			if (root->right != nullptr)//右孩子不为空
			{
				myfind(root->right, expectNumber - root->val, result, curpath);
			}
		}
		//下面这个出路径操作,可以完成以下情况的出路径
		/*
		1. 到达一个叶子节点了,但是这条路径的 和不等,所以返回上一层
		一直把节点退到可以开始下一条路径的地方。
		2. 找到一个正确的路径,把最后一个节点退出来。去找其他合适的路径

		*/
		curpath.pop_back();
	}
	vector<vector<int>> FindPath(TreeNode* root, int expectNumber) 
	{
		vector<vector<int>>result;
		if (root == nullptr)
			return result;

		vector<int>curpath;//保存一条条路径
		
		myfind(root, expectNumber, result, curpath);
		//找到路径集了,接下来进行 数组长度大的数组靠前
		int size = result.size();
		//作为数组个数的排序 此时的curpath 也正好为空,拿来用用
		multimap<int,vector<int>>mymap;
		for (int i = 0; i < size; ++i)
		{
			mymap.insert({ result[i].size(), result[i] });
			curpath.push_back(result[i].size());
		}
		sort(curpath.begin(), curpath.end());//从小到大排序
		vector<vector<int>>finnal_result;
		for (int i = size - 1; i >= 0; --i)
		{
			int len = curpath[i];
			multimap<int, vector<int>>::iterator it = mymap.find(len);
			finnal_result.push_back(it->second);
			mymap.erase(it);
		}
		return finnal_result;
	}
};
int main()
{
	Solution1 solution1;	
	Solution2 solution2;

	vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
	vector<int>vin({ 4,7,2,1,5,3,8,6 });//中

	TreeNode* this_new_tree = solution1.reConstructBinaryTree(pre, vin);//先 中序建树,上一个题目的
	vector<vector<int>>myvec = solution2.Print(this_new_tree);//按照之字形顺序打印 二叉树
	for (vector<int>&val : myvec)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}
	Solution solution3;
	vector<vector<int>>myvec2 = solution3.FindPath(this_new_tree, 18);
	for (vector<int>& val : myvec2)
	{
		for (int data : val)
			cout << data << " ";
		cout << endl;
	}

	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日14:45:19

(第四十九题)二叉树的下一个节点

2019年9月9日15:32:02
题目链接:
https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日14:48:05                             
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间:2019年9月9日15:58:08          
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <map>
#include <algorithm>
#include <iomanip>
using namespace std;



struct TreeLinkNode {
	int val;
	struct TreeLinkNode *left;
	struct TreeLinkNode *right;
	struct TreeLinkNode *next;//指向父节点的指针
	TreeLinkNode(int x) :val(x), left(nullptr), right(nullptr), next(nullptr) {}
};
/*
二叉树在中序遍历中的下一个节点的位置

二叉树的下一个节点,一共有以下情况:
1.二叉树为空,则返回空;
2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点.若这个
右孩子没有左孩子,那么下一个节点就是他自己。
3.节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。
4.节点是根节点,若是进不去2,则说明它没有右子树,最后当然 返回nullptr
*/
class Solution {
public:
	TreeLinkNode* GetNext(TreeLinkNode* pNode)
	{
		if (pNode == nullptr)//第一种情况
			return nullptr;

		if (pNode->right != nullptr)//第二种情况
		{
			TreeLinkNode* p = pNode->right;
			while (p->left != nullptr)//只要有左孩子 就一直向左下走
			{
				p = p->left;
			}
			return p;//右孩子没有左孩子,那么下一个节点就是他自己
		}
		
		while (pNode->next != nullptr)//第三种情况
		{
			//能进来,说明PNode节点没有右孩子,且不是根节点
			if (pNode == pNode->next->left)//这是 其是其爸的左孩子的情况
				return pNode->next;
			else pNode = pNode->next;//它是其爸的右孩子,去看看他爷爷吧
		}
		//以上几种都不是
		return nullptr;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
*/

int main()
{
	Solution solution;	
	//先把上面的树 给手工建立起来
	TreeLinkNode* root = nullptr;//根节点 没有爹
	TreeLinkNode* pArray[8] = { nullptr };
	for (int i = 0; i < 8; ++i)
	{
		pArray[i] = new TreeLinkNode(i + 1);
	}
	pArray[0]->left = pArray[1]; pArray[0]->right = pArray[2];
	pArray[1]->left = pArray[3];                              pArray[1]->next = pArray[0];
	pArray[2]->left = pArray[4]; pArray[2]->right = pArray[5]; pArray[2]->next = pArray[0];
	pArray[3]->right = pArray[6]; pArray[3]->next = pArray[1];
	pArray[4]->next = pArray[2];
	pArray[5]->left = pArray[7]; pArray[5]->next = pArray[2];
	pArray[6]->next = pArray[3];
	pArray[7]->next = pArray[5];

	cout << solution.GetNext(pArray[0])->val << endl;//1的后继是5  
	cout << solution.GetNext(pArray[2])->val << endl;//3的后继是8  第2种情况
	cout << solution.GetNext(pArray[7])->val << endl;//8的后继是6  第3种情况
	cout << solution.GetNext(pArray[6])->val << endl;//7的后继是2  第3种情况


	return 0;
}

/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日15:59:44

(第五十题)平衡二叉树

2019年9月9日16:12:57
题目链接:
https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述:
在这里插入图片描述
代码如下:

/**══════════════════════════════════╗
*作    者:songjinzhou                                                 ║
*CSND地址:https://blog.csdn.net/weixin_43949535                       ║
**GitHub:https://github.com/TsinghuaLucky912/My_own_C-_study_and_blog║
*═══════════════════════════════════╣
*创建时间:2019年9月9日16:04:50                           
*功能描述:                                                
*                                                                      
*                                                                      
*═══════════════════════════════════╣
*结束时间: 2019年9月9日16:12:01     
*═══════════════════════════════════╝
//                .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//            __.'              ~.   .~              `.__
//          .'//              西南\./联大               \\`.
//        .'//                     |                     \\`.
//      .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//    .'//.-"                 `-.  |  .-'                 "-.\\`.
//  .'//______.============-..   \ | /   ..-============.______\\`.
//.'______________________________\|/______________________________`.
*/


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <ctype.h>
#include <queue>
#include <list>
#include <map>
#include <math.h>
#include <algorithm>
#include <iomanip>
using namespace std;



struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
};
/*
该二叉树是否是平衡二叉树

平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:
它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 
最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 
这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,
1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
*/
class Solution {
public:
	int height_of_tree(TreeNode* root)
	{
		if (root == nullptr)
			return 0;
		return max(height_of_tree(root->left), height_of_tree(root->right)) + 1;
	}
	bool IsBalanced_Solution(TreeNode* pRoot) 
	{
		if (pRoot == nullptr)
			return true;
		return fabs(height_of_tree(pRoot->left) - height_of_tree(pRoot->right)) <= 1;
	}
};
/*
上面根据先 中序建树的样子如下:
vector<int>pre({ 1,2,4,7,3,5,6,8 });//先
vector<int>vin({ 4,7,2,1,5,3,8,6 });//中
                       1
			     2           3
			4             5     6
			    7             8
*/
int main()
{
	Solution solution;	
	//先把上面的树 给手工建立起来
	TreeNode* root = nullptr;//根节点 没有爹
	TreeNode* pArray[8] = { nullptr };
	for (int i = 0; i < 8; ++i)
	{
		pArray[i] = new TreeNode(i + 1);
	}
	pArray[0]->left = pArray[1]; pArray[0]->right = pArray[2];
	pArray[1]->left = pArray[3];                             
	pArray[2]->left = pArray[4]; pArray[2]->right = pArray[5]; 
	pArray[3]->right = pArray[6];

	pArray[5]->left = pArray[7];

	root = pArray[0];
	//上面的这棵树 肯定是平衡的
	if (solution.IsBalanced_Solution(root) == true)
		cout << "这棵树是平衡的" << endl;
	return 0;
}
/**
*备用注释:
*
*
*
*/

在这里插入图片描述
在这里插入图片描述
2019年9月9日16:14:55

猜你喜欢

转载自blog.csdn.net/weixin_43949535/article/details/100640227
今日推荐