判断二叉树是否平衡、求二叉树的镜像
思路:
判断一棵二叉树是否平衡,我们采用递归子问题的方法,先求出左右子树的深度,然后比较左右子树的深度,如果左右子树的深度差的绝对值小于2则表明此树平衡,由于此算法是不断递归给去求左右子树的深度,然后再判断子树是否平衡,根据左右子树平衡再判断是否平衡(需要重复遍历此树,即遍历左右子树),所以时间复杂度为O(N*N),给出算法代码如下:
int depth(Node* root)
{
if(root==NULL)
return 0;
int left=depth(root->left);
int right=depth(root->right);
return left>right?(left+1):(right+1);
}
bool isBalanced(TreeNode *root) {
if(root==NULL)
return true;
int left=depth(root->left);
int right=depth(root->right);
int tmp=abs(left-right);
if(tmp > 1)
return false;
return isBalanced(root->left) && isBalanced(root->right);
}
优化算法:我们在递归左右子树的时候,让子树返回自己的深度,并判断自己是否平衡(此处只遍历一遍二叉树,其实是用后序的顺序判断)。此处采用返回两个值,所以我们可以使用两个参数来完成!代码如下:
求二叉树的镜像就比较简单,只要判断节点不为空直接交换即可:
#include <iostream>
using namespace std;
#include <queue>
#include <stack>
namespace TREE_TOPIC
{
struct Node
{
int _value;
Node* _Lchild;
Node* _Rchild;
Node(int x)
:_value(x)
, _Lchild(NULL)
, _Rchild(NULL)
{}
};
//求二叉树是不是平衡树,时间复杂度为O(n)
bool IsBanlance(Node* root,int& depth)
{
if (NULL == root)
{
return true;
depth = 0;
}
int leftdepth = 0;
if (false == IsBanlance(root->_Lchild, leftdepth))
return false;
int rightdepth = 0;
if (false == IsBanlance(root->_Rchild, rightdepth))
return false;
depth = leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;
return abs(leftdepth - rightdepth) < 2;
}
//求二叉树的镜像,递归
void _GetMirrorTree(Node* root)
{
if (NULL == root)
return;
if (NULL == root->_Lchild && NULL == root->_Rchild)
return;
swap(root->_Lchild, root->_Rchild);
if (root->_Lchild)
_GetMirrorTree(root->_Lchild);
if (root->_Rchild)
_GetMirrorTree(root->_Rchild);
}
//求镜像,非递归
void MirrorNoR(Node* root)
{
if (NULL == root)
return;
stack<Node*> q;
q.push(root);
while (q.size())
{
Node* node = q.top();
q.pop();
if (NULL != node->_Lchild || NULL != node->_Rchild)
{
swap(node->_Lchild, node->_Rchild);
}
if (NULL != node->_Lchild)
q.push(node->_Lchild);
if (NULL != node->_Rchild)
q.push(node->_Rchild);
}
}
void GetMirrorTree(Node* root)
{
_GetMirrorTree(root);
}
//测试用层序遍历
void _Levelorder(Node* root)
{
queue<Node*> q;
if (root)
q.push(root);
while (!q.empty())
{
Node* front = q.front();
q.pop();
cout << front->_value << " ";
if (front->_Lchild)
{
q.push(front->_Lchild);
}
if (front->_Rchild)
{
q.push(front->_Rchild);
}
}
cout << endl;
}
void LeveOrder(Node* root)
{
cout << "层序:";
_Levelorder(root);
cout << endl;
}
void test()
{
Node* n1 = new Node(1);
Node* n2 = new Node(2);
Node* n3 = new Node(3);
Node* n4 = new Node(4);
Node* n5 = new Node(5);
Node* n6 = new Node(6);
n1->_Lchild = n2;
n1->_Rchild = n5;
n2->_Lchild = n3;
n2->_Rchild = n4;
n5->_Lchild = n6;
int a = 0;
//cout << IsBanlance(n1,a) << endl;
//GetMirrorTree(n1);
MirrorNoR(n1);
LeveOrder(n1);
}
}
一个m*n的矩阵,从左到右从上到下都是递增的,给一个数x,判断x是否在矩阵中
要求效率尽可能高
思路:
我们可以用数组嵌套来表示一个矩阵,然后从矩阵左下角开始判断,如果不相等每次先在一个数组里面找,所以时间复杂度为O(N)
代码:
#include <iostream>
using namespace std;
#include <vector>
bool IsInMartix(vector<vector<int>>& a, int x)
{
int m = a.size();
int n = a[0].size();
int i = 0;
int j = n - 1;
while (i < m && j >= 0)
{
if (x == a[i][j])
return true;
else if (x > a[i][j])
i++;
else
j--;
}
return false;
}
void test1()
{
//行数可以省略但是列数不能省略
vector<vector<int>> a = { { 1, 2, 8, 9 },
{ 2, 4, 9, 12 },
{ 4, 7, 10, 13 },
{ 6, 8, 11, 15 },
};
cout << IsInMartix(a, 22) << endl;
}