总结的部分题目思路与代码,待完善。
【剑指offer-第二版】部分题目与解答【C++版本】
题目:
题目一:二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
树的节点的定义为:
struct TreeNode {
int val;
treeNode *left;
treeNode *right;
treeNode(int x) :val(x), left(NULL), right(NULL) {}
};
解题思路:
1.使用递归很简单
2.广度优先遍历方法可以不适用递归来求解
可以AC的解法:使用递归【C++版本】
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
struct treeNode {
int val;
treeNode *left;
treeNode *right;
treeNode(int x) :val(x), left(NULL), right(NULL) {}
};
int TreeDepth(TreeNode* pRoot);
int main() {
//测试
treeNode *root = &treeNode(5);
treeNode *node1 = &treeNode(3);
treeNode *node2 = &treeNode(7);
root->left = node1;
root->right = node2;
treeNode *node3 = &treeNode(2);
treeNode *node4 = &treeNode(4);
treeNode *node5 = &treeNode(6);
treeNode *node6 = &treeNode(8);
node1->left = node3;
node1->right = node4;
node2->left = node5;
node2->right = node6;
cout << TreeDepth(root) << endl;
return 0;
}
//递归的求解
int TreeDepth(TreeNode* pRoot) {
if (pRoot == NULL)return 0;
int l = TreeDepth(pRoot->left)+1;
int r = TreeDepth(pRoot->right)+1;
return (l > r) ? l : r;
}
可以AC的方法:非递归(使用广度优先遍历)
//不使用递归
int TreeDepth(TreeNode* pRoot) {
if (pRoot == NULL)return 0;
queue<TreeNode *> nodeQueue;
nodeQueue.push(pRoot);
int depth = 0; //记录深度
int curNumPerLevel = 0; //下一层的叶节点个数,会随着新的左右子节点入队而增加,更新前的值为下一层的节点个数
int lastNumPerLevel = 1; //当前层的叶节点个数,随着节点出队列而逐渐减少,减少到1说明遍历完了当前层
while (!nodeQueue.empty()) {
TreeNode * tmpNode = nodeQueue.front();
nodeQueue.pop();
if (tmpNode->left) {
nodeQueue.push(tmpNode->left);
curNumPerLevel++;
}
if (tmpNode->right) {
nodeQueue.push(tmpNode->right);
curNumPerLevel++;
}
//lastNumPerLevel--;
//遍历完一层不仅要更新lastNumPerLevel,还要重置curNumPerLevel
if (!(--lastNumPerLevel)) {
depth++;
lastNumPerLevel = curNumPerLevel;
curNumPerLevel = 0;
}
}
return depth;
}
题目二:平衡二叉树
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
解题思路:
1.这个题目需要清除的指导平衡二叉树的定义:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
2.使用后序遍历,先判断左右子树是不是平衡的,如果是平衡的那么就分别记录左右子树的高度并返回,然后判断当前根节点是否是平衡的。
可以AC的解法:使用递归【C++版本】
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
struct treeNode {
int val;
treeNode *left;
treeNode *right;
treeNode(int x) :val(x), left(NULL), right(NULL) {}
};
bool IsBalanced_Solution(TreeNode* pRoot);
bool balanced_tree(TreeNode * pRoot, int *depth);
int main() {
//测试
treeNode *root = &treeNode(5);
treeNode *node1 = &treeNode(3);
treeNode *node2 = &treeNode(7);
root->left = node1;
root->right = node2;
treeNode *node3 = &treeNode(2);
treeNode *node4 = &treeNode(4);
treeNode *node5 = &treeNode(6);
treeNode *node6 = &treeNode(8);
node1->left = node3;
node1->right = node4;
node2->left = node5;
node2->right = node6;
if(IsBalanced_Solution(root)){
cout << "is avl." << endl;
}
else{
cout << "not avl." << endl;
}
return 0;
}
//二叉树的深度
//这个题可以使用树的深度来进行求解,但是存在重复遍历的问题,不是很理想
//一遍遍历的方法如下,在遍历的同时记录其深度,一遍判断其子树是否平衡
bool IsBalanced_Solution(TreeNode* pRoot) {
if (pRoot == NULL)return true;
int depth;
return balanced_tree(pRoot, &depth);
}
bool balanced_tree(TreeNode * pRoot, int *depth) {
if (pRoot == NULL) {
*depth = 0;
return true;
}
int left, right;
if (balanced_tree(pRoot->left, &left) && balanced_tree(pRoot->right, &right)) {
int dif = abs(left - right);
if (dif <= 1) {
*depth = 1 + ((left > right) ? left : right);
return true;
}
}
return false;
}