Leetcode 剑指系列 Day 15 搜索与回溯

这篇博客详细介绍了如何使用搜索与回溯算法解决LeetCode上的三个经典问题:二叉树中和为某一值的路径、二叉搜索树转化为双向链表以及找到二叉搜索树中的第k大节点。通过递归的先序遍历、后序遍历等方法,实现了高效解题策略。
摘要由CSDN通过智能技术生成

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值