出现次数>N/2的数
用碰撞抵消法找出一数,最后再数一遍验证是不是。比如从{2,3,1}中找到1,还要验证1是不是。若已知众数存在就不用验证。
已知众数存在时,也可用快速划分法直接找中位数。
int majorityElement(vector<int>& nums) {
int cand = INT_MIN;
int cnt = 0;
for (int num : nums) {
if (num == cand) {
cnt++;
} else if (cnt == 0) {
cand = num;
cnt++;
} else {
cnt--;
}
}
return cand;
}
所有出现次数>N/k的数
vector<int> majorityElement(vector<int>& nums) {
// 一般化,找出现次数>N/k的元素
// 用个map统计各候选的出现次数,当map.size()==k时删掉k个不同元素,
// 最后剩下的为候选
unordered_map<int, int> cnt;
for (auto num : nums) {
cnt[num]++;
if (cnt.size() == 3) {
auto it = cnt.begin();
while (it != cnt.end()) {
it->second--;
if (it->second == 0) {
it = cnt.erase(it);
} else {
it++;
}
}
}
}
// 需要验证候选的出现次数
for (auto &e : cnt) {
e.second = 0; // 给候选重新计数
}
for (auto num : nums) {
if (cnt.count(num)) cnt[num]++;
}
vector<int> ans;
for (auto &e : cnt) {
if (e.second > nums.size() / 3) {
ans.push_back(e.first);
}
}
return ans;
}
bst中找众数
vector<int> findMode(TreeNode* root) {
// bst中找众数,中序遍历找连续出现最多的数
vector<int> ans;
int prev = INT_MIN;
int count = 0, maxCount = INT_MIN;
inorder(root, prev, count, maxCount, ans);
return ans;
}
void inorder(TreeNode *root, int &prev, int &count, int &maxCount, vector<int> &ans) {
if (!root) return;
inorder(root->left, prev, count, maxCount, ans);
if (root->val != prev) count = 1;
else count++;
if (count > maxCount) {
maxCount = count;
ans = { root->val };
} else if (count == maxCount) {
ans.push_back(root->val);
}
prev = root->val;
inorder(root->right, prev, count, maxCount, ans);
}