Leetcode 剑指系列 Day 15 搜索与回溯
1.剑指 Offer 34. 二叉树中和为某一值的路径
解题思路:
设置一个返回值为void的先序遍历函数,逐个遍历树的各个节点并加入测试数组,当遍历至叶节点且sum值满足时,将测试数组push入答案二维数组。
算法步骤:
1.检查终止条件
当前节点为NULL,立即返回
2.当前节点运算步骤
将当前节点值push入测试数组
sum加上当前节点值并进行判断,若sum符合条件且该节点为叶节点,将此时的测试数组push入ans
3.查找左孩子节点
4.查找右孩子节点
5.pop出当前节点,sum减去当前节点值并退出
综上所述可以得到如下代码:
class Solution {
public:
void findWay(TreeNode* node, int target, int &sum, vector<vector<int>> &ans, vector<int> &testWay){
if(node == NULL) return;
testWay.push_back(node->val);
sum += node->val;
if(sum == target && node->left == NULL && node->right == NULL){
ans.push_back(testWay);
}
findWay(node->left, target, sum, ans, testWay);
findWay(node->right, target, sum, ans, testWay);
testWay.pop_back();
sum -= node->val;
return;
}
vector<vector<int>> pathSum(TreeNode* root, int target) {
vector<vector<int>> ans;
vector<int> testWay;
int sum = 0;
findWay(root, target, sum, ans, testWay);
return ans;
}
};
2.剑指 Offer 36. 二叉搜索树与双向链表
解题思路:
按后序遍历的方式从叶节点逐个按大小插入以head为头的链表(若从非叶结点就开始插入可能造成节点丢失)
插入的情况如下:
1.head指向为空,直接插入即可。
2.head非空,从head指向节点开始遍历,设定双指针,先指针 (hp) 从head指向节点开始,后指针 (ep) 从head开始,每轮循环往后遍历一次,情况如下:
(1) 当hp所指数大于当前数,当前节点同hp,ep建立连接
(2) 当hp为NULL,当前节点同ep建立连接
可得到如下代码:
class Solution {
public:
void insert(Node* node, Node* head){
Node* hp = head->right;
Node* ep = head;
while(hp != NULL && hp->val < node->val){
ep = hp;
hp = hp->right;
}
if(hp == NULL){
node->right = NULL;
node->left = ep;
ep->right = node;
}
else{
ep->right = node;
hp->left = node;
node->left = ep;
node->right = hp;
}
}
void pOrder(Node* node, Node* head){
if(node == NULL) return;
pOrder(node->left, head);
pOrder(node->right, head);
if(head->right == NULL){
head->right = node;
node->left = head;
node->right = NULL;
}
else{
insert(node, head);
}
}
Node* treeToDoublyList(Node* root) {
Node* head = new Node;
head->left = NULL;
head->right = NULL;
pOrder(root, head);
Node* mov = head;
while(mov->right != NULL) mov = mov->right;
if(head->right != NULL){
head->right->left = mov;
mov->right = head->right;
}
return head->right;
}
};
3.剑指 Offer 54. 二叉搜索树的第k大节点
解题思路:
中序遍历找到第k个节点即可
计算过程需要注意的点为:该题为求第k大的节点,所以应当从右节点先开始遍历
代码如下:
class Solution {
public:
int ans;
void mOrder(TreeNode* node, int k, int &num){
if(node == NULL || num == k) return;
mOrder(node->right, k, num);
if(num + 1 == k){
ans = node->val;
num++;
}
if(num == k) return;
num++;
mOrder(node->left, k, num);
}
int kthLargest(TreeNode* root, int k) {
int num = 0;
mOrder(root, k, num);
return ans;
}
};