Java&C++题解与拓展——leetcode1305.两棵二叉搜索树中的所有元素【归并排序】

113 阅读1分钟
每日一题做题记录,参考官方和三叶的题解

题目要求

image.png

思路:中序遍历+归并

【两个词总结完了思路】

  • 看到BFS立刻中序遍历一波,得到两个有序列表;
  • 对这两个列表归并排序,就拿两个指针分别从两个列表头开始往后轮,较小的一个放结果里指针后移。

Java

Java这里其实偷了个懒,原本到某一个列表末尾就不用判断直接把后面都放进结果就好(后面C++),这里用一个\infty数来标识末尾。

class Solution {
    int INF = 0x3f3f3f3f;
    public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
        List<Integer> res = new ArrayList<>();
        List<Integer> r1 = new ArrayList<>(), r2 = new ArrayList<>();
        DFS(root1, r1);
        DFS(root2, r2);
        int m = r1.size(), n = r2.size();
        int i = 0, j = 0;
        while(i < m || j < n) {
            int v1 = i < m ? r1.get(i) : INF, v2 = j < n ? r2.get(j) : INF; // 越界则赋值为∞
            if(v1 < v2) {
                res.add(v1);
                i++;
            }
            else {
                res.add(v2);
                j++;
            }
        }
        return res;
    }

    // 中序遍历
    void DFS(TreeNode root, List<Integer> r) {
        if(root == null)
            return;
        DFS(root.left, r); // 左
        r.add(root.val); // 中
        DFS(root.right, r); // 右
    }
}
  • 时间复杂度:O(m+n)O(m+n),中序遍历复杂度为O(m+n)O(m+n),归并复杂度为O(max(m,n))O(\max(m,n))
  • 空间复杂度:O(m+n)O(m+n)

C++

class Solution {
public:
    vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
        vector<int> res;
        vector<int> r1, r2;
        DFS(root1, r1);
        DFS(root2, r2);
        
        auto v1 = r1.begin(), v2 = r2.begin();
        while(true) {
            if(v1 == r1.end()) { // r1判断完了
                res.insert(res.end(), v2, r2.end()); // 把r2后面的直接放进res
                break; // 结束循环
            }
            if(v2 == r2.end()) { // r2判断完了
                res.insert(res.end(), v1, r1.end()); // 把r1后面的直接放进res
                break; // 结束循环
            }
            
            if(*v1 < *v2)
                res.push_back(*v1++);
            else
                res.push_back(*v2++);
        }
        
        return res;
    }

    // 中序遍历
    void DFS(TreeNode* root, vector<int> &r) {
        if(root) {
            DFS(root->left, r); // 左
            r.push_back(root->val); // 中
            DFS(root->right, r); // 右
        }
    }
};
  • 时间复杂度:O(m+n)O(m+n),中序遍历复杂度为O(m+n)O(m+n),归并复杂度为O(max(m,n))O(\max(m,n))
  • 空间复杂度:O(m+n)O(m+n)

总结

BFS就是明示中序遍历,后面归并(按双指针理解)也很简单啦,快乐结束今日题目,五月快乐。


欢迎指正与讨论!