持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
99. 恢复二叉搜索树
思路:
用三个新树,两个用来存储下次用来交换的结点,一个用来存储root后那个结点
代码:
class Solution {
public:
TreeNode*fir = nullptr;
TreeNode*sec = nullptr;
TreeNode*pre = nullptr;
void dfs(TreeNode*root) {
if (root == nullptr) return;
dfs(root->left);
if (pre) {
if (fir == nullptr && root->val <= pre->val) fir = pre;
if (fir && root->val <= pre->val) sec = root;
}
pre = root;
dfs(root->right);
}
void recoverTree(TreeNode* root) {
dfs(root);
int tmp = sec->val;
sec->val = fir->val;
fir->val = tmp;
}
};
100. 相同的树
思路:
注意是结点的左右都符合条件即可
即return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
而不是 return isSameTree(p->left, q->left) || isSameTree(p->right, q->right);
代码:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (!p && q) return false;
if (!q && p) return false;
if (!q && !p) return true;
if (p->val != q->val) return false;
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
109. 有序链表转换二叉搜索树
思路:
可以先将链表转为数组 或者 用快慢指针找出链表中间值,然后以中间值每次都构造树
代码:
class Solution {
public:
ListNode* getmid (ListNode*left, ListNode*right) {
ListNode*slow = left;
ListNode*fast = left;
while (fast != right && fast->next != right) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
TreeNode*gettree(ListNode*left, ListNode*right) {
if (left == right) return nullptr;
ListNode*mid = getmid(left, right);
TreeNode*a = new TreeNode(mid->val);
a->left = gettree(left, mid);
a->right = gettree(mid->next, right);
return a;
}
TreeNode* sortedListToBST(ListNode* head) {
return gettree(head, nullptr);
}
};
117. 填充每个节点的下一个右侧节点指针 II
思路:
层序遍历,连接即可
代码:
class Solution {
public:
Node* connect(Node* root) {
if(root == NULL) return root;
queue<Node*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
Node* last = NULL;
for (int i = 0; i < size; i++) {
Node* top = que.front();
que.pop();
if (top->left) { que.push(top->left); }
if (top->right) { que.push(top->right); }
if (i != 0) { last->next = top;} //让前一行的最后一个节点指向这行的第一个节点
last = top; //这行的结点连向后面的结点
}
}
return root;
}
};
116. 填充每个节点的下一个右侧节点指针
思路:
1.
递归
2.
与117思路一样
代码1:
class Solution {
public:
Node* connect(Node* root) {
if (root == NULL) return root;
if (root->left) {
root->left->next = root->right;
if (root->next) {
root->right->next = root->next->left;
}
}
connect(root->left);
connect(root->right);
return root;
}
};
代码2:
class Solution {
public:
Node* connect(Node* root) {
if(root == NULL) return root;
queue<Node*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
Node* last = NULL;
for (int i = 0; i < size; i++) {
Node* top = que.front();
que.pop();
if (top->left) { que.push(top->left); }
if (top->right) { que.push(top->right); }
if (i != 0) { last->next = top;} //如果pre为空就表示node节点是这一行的第一个,
//没有前一个节点指向他,否则就让前一个节点指向他
last = top; //然后再让当前节点成为前一个节点
}
}
return root;
}
};
199. 二叉树的右视图
思路:
层序遍历找到que.size() - 1那个值即可
代码:
class Solution {
public:
vector<int> ret;
vector<int> rightSideView(TreeNode* root) {
if (root == nullptr) return ret;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int z = que.size();
for (int i = 0; i < z; i++) {
TreeNode* m = que.front();
que.pop();
if (i == z - 1) {
ret.push_back(m->val);
}
if (m->left) {
que.push(m->left);
}
if (m->right) {
que.push(m->right);
}
}
}
return ret;
}
};