1 条题解
-
0
思路与算法
按顺序下标读取结点是否存在,不比较字母内容。从根的左右孩子开始成对比较:两处都空则相同,恰一处空则不对称,否则递归比较左边的左孩子与右边的右孩子,以及左边的右孩子与右边的左孩子。空树直接对称。
正确性说明
空/非空条件是结构相等的必要条件;两点均存在时,镜像映射必须交换左右方向。因此两个交叉孩子对子都镜像相同当且仅当当前两棵子树镜像相同,按树高归纳即可。结点字母不属于结构条件,不影响判断。
复杂度
读取与存储O(L),每对存在结点至多访问一次,时间O(L)。顺序树下标每层倍增,递归栈O(log L);字符串空间O(L),初始化已计入。
易错点
2i和2i+1是1-based下标,转成字符串0-based时要用2i+1、2i+2。字符串外是空。ABCDE按已明确的堆式表示不对称,不能为保留有歧义旧样例而只检查根的两个孩子。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; int main() { string s; cin >> s; function<bool(int, int)> mirror = [&](int a, int b) { bool aa = a < (int)s.size() && s[a] != '#', bb = b < (int)s.size() && s[b] != '#'; if (!aa || !bb) return aa == bb; return mirror(a * 2 + 1, b * 2 + 2) && mirror(a * 2 + 2, b * 2 + 1); }; cout << ((s[0] == '#' || mirror(1, 2)) ? "Yes" : "No") << '\n'; }
- 1