寻找多数元素(leetcode169)
令A[1...n]是一个整数数列,A中的整数a如果出现的次数多于[n/2],那么称a为多数元素。
有一个比较漂亮的求解法,我们用归纳法导出这个算法,这个算法的实质是基于下面的观察结论。
观察结论:在原序列中去除两个不同的元素后,那么原序列中的多数元素在新序列中还是多数元素。
其实就是遍历一遍,将互异的划掉。
递归版:
int candidate(vector<int>& nums, int m)
{
int j = m, n = nums.size(), cnt = 1, c = nums[m];
while(j < n-1 && cnt > 0)
{
j++;
if(nums[j] == c) cnt++;
else cnt--;
}
if(j == n-1) return c;
else return candidate(nums, j+1);
}
int majorityElement(vector<int>& nums) {
return candidate(nums, 0);
}
非递归版:
int majorityElement(vector<int>& nums) {
int count = 0;
int candidate = 0;
for(int i = 0; i < nums.size(); i++) {
if(count == 0) {
candidate = nums[i];
count = 1;
} else {
if(nums[i] == candidate) {
count++;
} else {
count--;
}
}
}
return candidate;
}
好像这也叫摩尔投票法(不清楚,反正我在课本上学的)
还有一种不错的解法,利用位运算,将这个大多数按位来建立,从0到31位,每次统计下数组中该位上0和1的个数,如果1多,那么将结果 res 中该位变为1,最后累加出来的 res 就是过半数了
int majorityElement(vector<int>& nums) {
int res = 0, n = nums.size();
for (int i = 0; i < 32; ++i) {
int ones = 0, zeros = 0;
for (int num : nums) {
if (ones > n / 2 || zeros > n / 2) break;
if (num & (1 << i)) ++ones;
else ++zeros;
}
if (ones > zeros) res |= (1 << i);
}
return res;
}
另一种显然的方法就是利用map,这里可以使用unordered_map,其本质是哈希
int majorityElement(vector<int>& nums) {
unordered_map<int, int>mp;
int n = nums.size();
for(int i = 0;i < n;i++)
{
int tmp = ++mp[nums[i]];
if(tmp > n/2) return nums[i];
}
return -1;
}
参考链接:https://www.cnblogs.com/grandyang/p/4233501.html
原编辑时间 2020-03-14 13:22
个性签名:时间会解决一切
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2019-03-14 利用Google插件web server for chrome部署静态网页