BM51 数组中出现次数超过一半的数字
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
思考:
这道题目有多种处理方式,
- 用空间换时间的方法,
- 先排序,然后直接返回中位数
- 用投票法,进行两两抵消
代码:
空间换时间
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
int a[50001];
for (int i = 0;i < numbers.size();i++) a[numbers[i]]++;
for (int i = 0;i < 50001;i++) if (a[i] > numbers.size()/2) return i;
return 0;
}
};
排序
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
sort(numbers.begin(), numbers.end());
return numbers[numbers.size()/2];
}
};
投票法
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
int num = 0;
int cond = -1;
for (int i = 0;i < numbers.size();i++)
{
if (num == 0) {
cond = numbers[i];
num = 1;
}
else {
if (numbers[i] == cond) num++;
else num--;
}
}
return cond;
}
};
BM52 数组中只出现一次的两个数字
一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思考:
这次给的数组大小是1000000,用空间换时间会炸内存,所以用其他两种解法。
- 排序法
- 异或运算法
代码:
排序后处理
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @return int整型vector
*/
vector<int> FindNumsAppearOnce(vector<int>& nums) {
// write code here
sort(nums.begin(), nums.end());
int d = nums[0];
vector<int> res;
if (nums[0] != nums[1]) res.push_back(nums[0]);
for (int i = 1;i < nums.size()-1;i++)
{
if (nums[i] != nums[i+1] && nums[i] != nums[i-1]) {
res.push_back(nums[i]);
}
}
if (res.size() == 1) res.push_back(nums[nums.size()-1]);
return res;
}
};
异或运算法
对于异或运算,
https://blog.youkuaiyun.com/cuixianlong/article/details/90064348
这篇博客简单介绍了基础的性质和用法
因为a ^ b ^ c ^ b ^ c = a ,所以我们试着将整个数组拆分为两段,即满足a ^ b ^ c ^ b ^ c = a, e ^ b ^ c ^ b ^ c = e,这样就得到了两个不同的元素
对于整段运算,结果为a ^ e,只需要明白二者从哪一位开始不同,就能将其拆分为两段
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @return int整型vector
*/
vector<int> FindNumsAppearOnce(vector<int>& nums) {
// write code here
vector<int> res(2, 0);
int ab = 0;
for (int i = 0;i < nums.size();i++) ab ^= nums[i];
int k = 1; // 数位检测器
while ((ab & k) == 0) {
k <<= 1; // zuo移
}
for (int i = 0; i < nums.size();i++) {
if (
(nums[i] & k) == 0
) res[0] ^= nums[i];
else res[1] ^= nums[i];
}
sort(res.begin(),res.end());
return res;
}
};
BM53 缺失的第一个正整数
给定一个无重复元素的整数数组nums,请你找出其中没有出现的最小的正整数
思路:
2^(31)−1不能开数组了,用map实现哈希表
代码:
class Solution {
public:
int minNumberDisappeared(vector<int>& nums) {
int n = nums.size();
unordered_map<int, int> mp;
for(int i = 0; i < n; i++)
mp[nums[i]]++;
int res = 1;
while(mp.find(res) != mp.end())
res++;
return res;
}
};
922

被折叠的 条评论
为什么被折叠?



