有这么一个文件,里面存放着99999个数字用,隔开,这些数字的范围是1-100000,
- 文件中数字没有重复并且这些数字是乱序的。
- 要求: 找到这个不存在的数字,时间复杂度,空间复杂度尽量低。
- 例如:存放着2-100000的数字,没有存放1,程序运行结束后应该返回的是这个数字 1
有这么一个文件,里面存放着99999个数字用,隔开,这些数字的范围是1-100000,
换一个思路,python实现
def getNumb(nums):
s = 4999950000 # sum([i for i in range(10_0000)])
for i in nums:
s -= i
return s
# 题中输入为例,2-99999,返回 1
assert 1 == getNumb([i for i in range(2,10_0000)])
这道题如果语言环境如果支持大整数处理,还是用数学特性是最方便的,而且也容易理解,速度快,且空间占用小,就是weak_ptr的思路。
如果不支持大整数的处理,可以考虑用位运算的异或来处理,因为任何数异或本身后为0x0
,而0x0
异或任何数N结果还是N。而且异或的方法在支持异或的语言中都能实现。其javascript语言实现如下(其它支持位运算的语言大同小异):
// 具体方法
function getLoseNum( Arr ){
rt=0x0;
for (let i=0;i<100000;i++){
rt=rt ^ Arr[i] ^ i ;
}
return (rt ^ 100000) ;
}
// 下面是测试
let arr=[]
for (let i=0;i<54640;i++) {arr.push(i+1)}
for (let i=54641;i<100000;i++) {arr.push(i+1)}
console.log( getLoseNum( arr) )
let brr=[]
for (let i=1;i<100000;i++){brr.push(i+1) }
console.log( getLoseNum( brr) )
let crr=[]
for (let i=1;i<100000;i++){crr.push(i) }
console.log( getLoseNum( crr) )
支持位运算运算异或,这个算法也是相当的快,而且空间占用,比大整数运算还小。而且这个算法实现也特别简洁。
其它诸如标记法,不但要额外占用存储空间,还需要额外遍历1次,都不如这两种方法对这种题适合。
随便写的,可能还有更优解,不过我懒得考虑了,抛砖引玉
List<Integer> getNumb(List<Integer> list){
List<Integer> allNumb = new ArrayList<>();
for (int i =1;i<=100000;i++){
allNumb.add(i);
}
for (Integer numb:list){
allNumb.remove(numb);
}
return allNumb;
}
思路和上面的兄弟一样,只是用了数组,开销可能会更小点;
List<Integer> getNumb(int[] nums) {
int len = nums.length;
int[] uses = new int[100000];
for (int i = 0; i < len; i++) {
uses[nums[i]] = nums[i];
}
List<Integer> ans = new ArrayList<>();
for (int use : uses) {
if (use == 0) ans.add(use);
}
return ans;
}
4 回答1.6k 阅读✓ 已解决
4 回答1.4k 阅读✓ 已解决
1 回答2.6k 阅读✓ 已解决
4 回答2.1k 阅读
2 回答795 阅读✓ 已解决
2 回答1.7k 阅读
2 回答1.4k 阅读
考虑用 bit 来处理,1个int是 32个数字,