1. 题目来源
2. 题目解析
挺不错的一道题,dfs
搜索二叉树中一个值唯一的节点,且需要记录其深度、父节点的值。
最后就判断下深度是否相等和父节点是否不同即可。
注意在 dfs
过程中 dfs(root->left, d + 1, root->val, x, y);
若将其写为 dfs(root->left, ++ d, root->val, x, y);
这里是将当前层的 d
进行了 +1,操作的,是实打实的作用到了 d
身上,所以需要回溯,退回到上一层。但是一般情况下都不这样写,所以就忽略了中间的回溯步骤。 但是 dfs(root->left, d ++, root->val, x, y);
实际上传入下一层的 d
并没有 +1,还是当前的 d
因为这是后置 ++,但是 dfs
这个函数结束后,当前层的 d
确实是自增了 1。所以紧接着的下一次 dfs
传参的 d++
是正确的,故中间的回溯是没有意义的。
总结:
- 前置 ++ 改变了当前层的
d
,且改变了传入下层的d
,后续dfs
需要回溯会当前的d
,即d -- ;
。 - 后置 ++ 改变了当前层的
d
,不改变下层的d
。 与dfs
思想相悖,层数不会递增,且如果回溯的话,是恢复回当前层的d
,但是下次的dfs
如果继续采用d ++
,仍然是没有意义的。
具体可以看看下面的测试代码。
测试:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int d;
void fun(int d) {
cout << "fun " << d << endl;
}
int main() {
fun(d ++);
cout << "main " << d << endl;
fun(d ++);
cout << "main " << d << endl;
return 0;
}
/*
fun 0
main 1
fun 1
main 2
*/
dfs 代码:
/**
* 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:
int d1, d2, p1, p2; // 两个深度,两个父节点值
// 根-深度-上层父节点值-x-y
void dfs(TreeNode* root, int d, int t, int x, int y) {
if (!root) return ;
if (root->val == x) d1 = d, p1 = t;
else if (root->val == y) d2 = d, p2 = t;
dfs(root->left, d + 1, root->val, x, y);
dfs(root->right, d + 1, root->val, x, y);
}
bool isCousins(TreeNode* root, int x, int y) {
dfs(root, 0, root->val, x, y);
return (d1 == d2 && p1 != p2);
}
};
dfs 前置++,回溯:
/**
* 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:
int d1, d2, p1, p2; // 两个深度,两个父节点值
// 根-深度-上层父节点值-x-y
void dfs(TreeNode* root, int d, int t, int x, int y) {
if (!root) return ;
if (root->val == x) d1 = d, p1 = t;
else if (root->val == y) d2 = d, p2 = t;
// 前置 ++ 改变了当前层的 d,且改变了传入下层的 d,后置 ++ 改变了当前层的 d,不改变下层的 d
dfs(root->left, ++ d, root->val, x, y);
d -- ; // 回溯
dfs(root->right, ++ d, root->val, x, y);
}
bool isCousins(TreeNode* root, int x, int y) {
dfs(root, 0, root->val, x, y);
return (d1 == d2 && p1 != p2);
}
};
bfs 代码:
/**
* 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:
int d1, d2, p1, p2;
bool isCousins(TreeNode* root, int x, int y) {
queue<pair<TreeNode*, int>> q; // 当前点,父节点值
q.push(make_pair(root, 0));
int d = 0;
while (q.size()) {
d ++ ;
int len = q.size();
for (int i = 0; i < len; i ++ ) {
auto t = q.front(); q.pop();
if (t.first->val == x) d1 = d, p1 = t.second;
else if (t.first->val == y) d2 = d, p2 = t.second;
if (t.first->left) q.push(make_pair(t.first->left, t.first->val));
if (t.first->right) q.push(make_pair(t.first->right, t.first->val));
}
}
return d1 == d2 && p1 != p2;
}
};