给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
示例 1:
给定的树 s:
给定的树 t:
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
示例 2:
给定的树 s:
给定的树 t:
返回 false。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
getMaxElem(s, maxElem);
getMaxElem(t, maxElem);
lNull = maxElem + 1;//将lNull设置为此值作为唯一标记值
rNull = maxElem + 2;//将rNull设置为此值作为唯一标记值
vector<int> sVec;
vector<int> tVec;
getTreePreArray(s, sVec);
getTreePreArray(t, tVec);
return Sunday(sVec, tVec);
}
private:
int maxElem;
int lNull, rNull;
//得到树的先序遍历,对于左子树为空的节点,插入lNull值,对于右子树为空的节点,插入rNull值
void getTreePreArray(TreeNode* root, vector<int>& vec) {
if(!root)
return;
vec.push_back(root->val);
if(root->left)
getTreePreArray(root->left, vec);
else
vec.push_back(lNull);
if(root->right)
getTreePreArray(root->right, vec);
else
vec.push_back(rNull);
}
//获取树中最大值
void getMaxElem(TreeNode* root, int& maxElem) {
if(!root)
return;
maxElem = max(maxElem, root->val);
getMaxElem(root->left, maxElem);
getMaxElem(root->right, maxElem);
}
//sunday字符串匹配算法
bool Sunday(vector<int> sVec, vector<int> tVec) {
int sIndex = 0, tIndex = 0;
//当sVec中剩余元素个数大于等于tVec中剩余元素个数时执行匹配算法
while (sVec.size() - sIndex >= tVec.size() - tIndex) {
//当前匹配到tVec中最后一个元素且匹配完成
if (tIndex == tVec.size())
return true;
//当前元素匹配
if (sVec[sIndex] == tVec[tIndex]) {
sIndex++;
tIndex++;
}
else {
//出现不匹配且从这次匹配的第一个元素开始所需的元素个数不足,即剩余元素个数<=(主要为==)tVec中元素个数
if (sIndex - tIndex + tVec.size() >= sVec.size())
break;
//获取此匹配序列之外的第一个值
int val = sVec[sIndex - tIndex + tVec.size()];
bool isFind = false;
//寻找tVec中是否有这个值,并移动tVec位置重新匹配
for (int i = tVec.size() - 1; i >= 0; i--) {
if (tVec[i] == val) {
sIndex = sIndex - tIndex + tVec.size() - i;
isFind = true;
break;
}
}
if (!isFind) {
sIndex = sIndex - tIndex + tVec.size() + 1;
}
tIndex = 0;
}
}
return false;
}
};