2022-6-15 出现次数最多的子树元素和,节点与其祖先之间的最大差值,输出二叉树,找出第 K 小的数对距离

1. 出现次数最多的子树元素和

给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。

一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。

Example 1

输入: root = [5,2,-3]
输出: [2,-3,4]

Example 2

输入: root = [5,2,-5]
输出: [2]

Constraints:

  • 节点数在 [1, 10^4] 范围内
  • -10^5 <= Node.val <= 10^5

代码 [DFS]

class Solution {
private:
    unordered_map<int, int> mp; // sum, cnt

    int dfs(TreeNode *root) {
        if (!root) return 0;
        int sum = root->val + dfs(root->left) + dfs(root->right);
        mp[sum]++;
        return sum;
    }

public:
    vector<int> findFrequentTreeSum(TreeNode *root) {
        mp.clear();
        dfs(root);
        int maxVal = -1;
        for (auto it = mp.begin(); it != mp.end(); ++it) maxVal = max(maxVal, it->second);
        vector<int> result;
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            if (it->second == maxVal) result.push_back(it->first);
        }
        return result;
    }
};

2. 节点与其祖先之间的最大差值

给定二叉树的根节点 root,找出存在于 不同 节点 AB 之间的最大值 V,其中 V = |A.val - B.val|,且 AB 的祖先。

(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)

Example 1

输入:root = [8,3,10,1,6,null,14,null,null,4,7,13]
输出:7
解释: 
我们有大量的节点与其祖先的差值,其中一些如下:
|8 - 3| = 5
|3 - 7| = 4
|8 - 1| = 7
|10 - 13| = 3
在所有可能的差值中,最大值 7 由 |8 - 1| = 7 得出。

Example 2

输入:root = [1,null,2,null,0,3]
输出:3

Constraints:

  • 树中的节点数在 25000 之间。
  • 0 <= Node.val <= 10^5

代码 [DFS]

class Solution {
private:
    pair<int, int> dfs(TreeNode *root, int &result) {
        pair<int, int> le = root->left ? dfs(root->left, result) : pair<int, int>{root->val, root->val};
        pair<int, int> ri = root->right ? dfs(root->right, result) : pair<int, int>{root->val, root->val};
        int minVal = min(le.first, ri.first), maxVal = max(le.second, ri.second);
        int maxDiff = max(abs(root->val - minVal), abs(root->val - maxVal));
        result = max(result, maxDiff);
        return {min(minVal, root->val), max(maxVal, root->val)};
    }

public:
    int maxAncestorDiff(TreeNode *root) {
        int result = 0;
        dfs(root, result);
        return result;
    }
};

3. 输出二叉树

Given the root of a binary tree, construct a 0-indexed m x n string matrix res that represents a formatted layout of the tree. The formatted layout matrix should be constructed using the following rules:

  • The height of the tree is height and the number of rows m should be equal to height + 1.
  • The number of columns n should be equal to 2height+1 - 1.
  • Place the root node in the middle of the top row (more formally, at location res[0][(n-1)/2]).
  • For each node that has been placed in the matrix at position res[r][c], place its left child at res[r+1][c-2height-r-1] and its right child at res[r+1][c+2height-r-1].
  • Continue this process until all the nodes in the tree have been placed.
  • Any empty cells should contain the empty string "".

Return the constructed matrix res.

Example 1

Input: root = [1,2]
Output: 
[["","1",""],
 ["2","",""]]

Example 2

Input: root = [1,2,3,null,4]
Output: 
[["","","","1","","",""],
 ["","2","","","","3",""],
 ["","","4","","","",""]]

Constraints:

  • The number of nodes in the tree is in the range [1, 2^10].
  • -99 <= Node.val <= 99
  • The depth of the tree will be in the range [1, 10].

代码 [DFS]

class Solution {
private:
    int getHeight(TreeNode *root) { return root ? 1 + max(getHeight(root->left), getHeight(root->right)) : 0; }

    void dfs(vector<vector<string>> &result, TreeNode *root, int x, int y, int dy) {
        if (dy == 0) return;
        if (root->left) {
            result[x + 1][y - dy] = to_string(root->left->val);
            dfs(result, root->left, x + 1, y - dy, dy >> 1);
        }
        if (root->right) {
            result[x + 1][y + dy] = to_string(root->right->val);
            dfs(result, root->right, x + 1, y + dy, dy >> 1);
        }
    }

public:
    vector<vector<string>> printTree(TreeNode *root) {
        int height = getHeight(root);
        int weight = (1 << height) - 1;
        vector<vector<string>> result(height, vector<string>(weight, ""));
        result[0][weight >> 1] = to_string(root->val);
        if (height > 1) dfs(result, root, 0, weight >> 1, 1 << (height - 2));
        return result;
    }
};

4. 找出第 K 小的数对距离

数对 (a,b) 由整数 ab 组成,其数对距离定义为 ab 的绝对差值。

给你一个整数数组 nums 和一个整数 k ,数对由 nums[i]nums[j] 组成且满足 0 <= i < j < nums.length 。返回 所有数对距离中k 小的数对距离。

Example 1

输入:nums = [1,3,1], k = 1
输出:0
解释:数对和对应的距离如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距离第 1 小的数对是 (1,1) ,距离为 0 。

Example 2

输入:nums = [1,1,1], k = 2
输出:0

Constraints:

  • n == nums.length
  • 2 <= n <= 10^4
  • 0 <= nums[i] <= 10^6
  • 1 <= k <= n * (n - 1) / 2

代码 [二分]

int smallestDistancePair(vector<int> nums, int k) {
    sort(nums.begin(), nums.end());
    int n = nums.size(), left = 0, right = nums.back() - nums.front() + 1;
    while (left < right) {
        int mid = left + ((right - left) >> 1);
        int cnt = 0;
        for (int j = 0; j < n; j++) {
            int i = lower_bound(nums.begin(), nums.begin() + j, nums[j] - mid) - nums.begin();
            cnt += j - i;
        }
        cnt < k ? left = mid + 1 : right = mid;
    }
    return left;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值