501. Find Mode in Binary Search Tree

https://leetcode.com/problems/find-mode-in-binary-search-tree/

Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST.

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than or equal to the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

For example:
Given BST [1,null,2,2],

   1
    \
     2
    /
   2

return [2].

Note: If a tree has more than one mode, you can return them in any order.

Follow up: Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

算法思路:

// 实际上,这个算法是适合任何二叉树的findMode
// 因此,没有利用BST树的性质,空间复杂度O(n)
class Solution {
public:
    vector findMode(TreeNode* root) {
        vector arr;
        inorder(root, arr);
        int count = 0;
        unordered_map um;
        for (auto& x : arr) {
            um[x]++;
            count = max(count, um[x]);
        }
        vector res;
        for (auto& pair : um) {
            if (pair.second == count) {
                res.push_back(pair.first);
            }
        }
        return res;
    }
private:
    void inorder(TreeNode* node, vector& arr) {
        if (node == nullptr) return;
        if (node->left) inorder(node->left, arr);
        arr.push_back(node->val);
        if (node->right) inorder(node->right, arr);   
    }
};

接下来真正的利用二叉树的性质,降低空间复杂度

class Solution {
public:
    vector findMode(TreeNode* root) {
        vector res;
        int prev = INT_MIN;
        int count = 0;
        int max = 0;
        inorder(root, res, prev, count, max);
        return res;
    }
private:
    void inorder(TreeNode* node, vector& res, int& prev, int& count, int& max) {
        if (node == nullptr) return;
        if (node->left) inorder(node->left, res, prev, count, max);
        if (node->val == prev) {
            count++;
        } else {
            count = 1;
        }
        if (count > max) {
            max = count;
            res.clear();
            res.push_back(node->val);
        } else if (count == max) {
            res.push_back(node->val);
        }
        prev = node->val;
        if (node->right) inorder(node->right, res, prev, count, max);   
    }
};

 或者第一遍先找出最大的cnt,接着第二遍找出个数为cnt的数字(以下代码来自提交代码)

class Solution {
public:
    vector findMode(TreeNode* root) {
        dfs(root, true);
        cnt = 1;
        prev = nullptr;
        dfs(root, false);
        return res;
    }
private:
    vector res;
    int cnt = 1, maxCnt = 1;
    TreeNode *prev = nullptr;
    void dfs(TreeNode *node, bool pass) {
        if (node == nullptr)
            return;
        dfs(node->left, pass);
        if (prev != nullptr) {
            if (prev->val == node->val)
                cnt++;
            else
                cnt = 1;
        }
        if (pass)
            maxCnt = max(cnt, maxCnt);
        else if (cnt == maxCnt)
            res.push_back(node->val);
        prev = node;
        dfs(node->right, pass);
    }
};

 

你可能感兴趣的:(leetcode)