二叉搜索树中的众数(C++)

501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

示例 1:
输入:root = [1,null,2,2]
输出:[2]

思路:二叉搜索树,中序遍历是有序的,所以中序遍历二叉树,相同的值一定相邻,如果当前节点与上一个节点值相同,计数器+1;不同,计数器置1。统计每个值出现的次数,并把当前出现次数最多的值加入结果集,记录该值出现的次数。遇见出现次数更多的值,更新结果集,遇见与出现次数最多的相同的值,把该值加入结果集。

递归法:

class Solution {	//501. 二叉搜索树中的众数  递归法
public:
	vector<int> result;
	int count = 1;	//记录每个值出现的次数
	int maxVal = INT_MIN;	//记录众数出现的次数
	TreeNode* pre = nullptr;	//上一个节点
	void traversal(TreeNode* root) {
		if (root == nullptr) return;
		traversal(root->left);	//左
		if (pre == nullptr) {	//先把根节点放进结果集
			result.push_back(root->val);
			maxVal = 1;
		}
		if (pre != nullptr) {	//中
			if (pre->val == root->val) {	//当前元素值和前一个元素值相等时,计数+1,如果此时maxVal与count相等,在结果集里加入新的元素pre->val
				count++;
				if (maxVal == count) {
					result.push_back(pre->val);
				}
			}
			else {	//当前元素值和前一个元素值不相等,说明前一个值已经统计完,重新开始计数,令count=1,如果此时maxVal=count,将当前节点值加入结果集
				count = 1;
				if (maxVal == count) {
					result.push_back(root->val);
				}
			}
			if (maxVal < count) {	//在遍历中,如果count>maxVal,说明之前找的都不是众数,就将整个结果集清空,加入新的元素值pre->val
				result.clear();
				maxVal = count;
				result.push_back(pre->val);
			}
		}
		pre = root;	//更新上一个节点
		traversal(root->right);	//右
	}

	vector<int> findMode(TreeNode* root) {
		traversal(root);
		return result;
	}
};

迭代法:

class Solution {	//501. 二叉搜索树中的众数  迭代法
public:
	vector<int> findMode(TreeNode* root) {
		stack<TreeNode*> stk;
		vector<int> result;
		int count = 1;	//记录每个值出现的次数
		int maxVal = INT_MIN;	//记录众数出现的次数
		TreeNode* pre = nullptr;	//上一个节点
		TreeNode* cur = root;
		while (cur != nullptr || !stk.empty()) {
			if (cur != nullptr) {	
				stk.push(cur);	//将访问到的节点加入栈
				cur = cur->left;
			}
			else {	//中
				cur = stk.top();
				stk.pop();
				if (pre == nullptr) {	//先把根节点放进结果集
					result.push_back(cur->val);
					maxVal = 1;
				}
				if (pre != nullptr) {	
					if (pre->val == cur->val) {	//当前元素值和前一个元素值相等时,计数+1,如果此时maxVal与count相等,在结果集里加入新的元素pre->val
						count++;
						if (maxVal == count) {
							result.push_back(pre->val);
						}
					}
					else {	//当前元素值和前一个元素值不相等,说明前一个值已经统计完,重新开始计数,令count=1,如果此时maxVal=count,将当前节点值加入结果集
						count = 1;
						if (maxVal == count) {
							result.push_back(cur->val);
						}
					}
					if (maxVal < count) {	//在遍历中,如果count>maxVal,说明之前找的都不是众数,就将整个结果集清空,加入新的元素值pre->val
						result.clear();
						maxVal = count;
						result.push_back(pre->val);
					}
				}
				pre = cur;	//更新上一个节点
				cur = cur->right;	//右
			}
			
		}
		return result;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海螺蜜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值