1:第一题,给一个40亿个数的顺序32位整数集合,寻找一个缺失数,时空复杂度O(n)。
题目给的是2^32的数据范围,就是32位数,但事实上换成3位数字道理一样的,所以就以3位数字(0-7)为例:
比如:0, 1, 2, 3, 4, 6, 7,缺失值是5。
好了接下来写出他们的二进制:
0---000 1---001 2---010 3---011
4---100 6---110 7---111
然后开辟两个数组,cache0和cache1,从最低位开始把相应数字放在相应cache中
第一波:
cache0: 0, 2, 4, 6
cache1:1, 3, 7
cache1的size小,说明cache1中有缺失值,且缺失值这一位为1
第二波:检查次低位
cache1:3, 7
cache0:1
cache0的size小,说明cache0中有缺失值,且这一位为0
第三波同理:得到101 = 5
代码如下:
#include <iostream>
#include <vector>
using namespace std;
const int numSize = 3;
const int maxNum = 7;
vector<int> nums = {0, 1, 2, 3, 4, 5, 7}; //0~8中缺少一些数
int main() {
int ans = 0;
vector<int> curArr = nums;
vector<int> cache0, cache1;//把位0和1的数字分开
for (int i = 0; i < 3; ++i) {
cache0.clear(), cache1.clear();
//区分位的数值并分开保存
for (int j = 0; j < curArr.size(); ++j) {
int mask = 1 << i;
if (curArr[j] & mask) {
cache1.push_back(curArr[j]);
}
else {
cache0.push_back(curArr[j]);
}
}
//哪个数值数量少就说明存在缺失值
if (cache0.size() < cache1.size()) {
curArr = cache0;
}
else {
curArr = cache1;
ans |= 1 << i;
}
if (curArr.size() == 0) {
break;
}
}
cout << ans << endl;
system("pause");
return 0;
}
2:第二题,给一个长度为n的字符串,旋转a后输出,例如:abcdef,3.输出:defabc。
这个可以模拟一下,巨著《C程序设计语言》的作者之一认为个操作应该是程序员的常识,并且这个算法多次被用在真实系统中。
伪代码如下:
reverse(str, 0, 2);
reverse(str, 3, len - 1);
reverse(str, 0, len - 1);
3:字典的变位词集合:变位词就是由相同的字母的不同顺序组成的单词,例如pots和stop就是变位词。
这个嘛排序一下:
pots排序后和stop肯定一样的,都是opst,然后编码成o1p1s1t1就好啦。