如何用最省内存的方式实现快速查找功能?
思考题:
对于1000万个整数数据,每个数据占8个字节,如何快速的判断某个整数是否出现在这1000万数据中呢? 内存空间不超过100M;
二分查找针对于有序集合的查找方法,每次都与区间的中间数据比对大小,缩小查找区间的范围,下图是一次二分查找的过程,low和high代表的是待查找区间的下标,mid表示待查找区间的中间元素下标。
二分查找高效,假设数据大小为n,每次查找完数据之后都会缩小为原来的一般,就是除以2,最坏的情况,直到查找区间缩小为空,才会停止。
当n/2^k=1时,k=log2(n),所以时间复杂度就是O(logn);
二分查找非递归算法
public int bSearch(int[] a,int value){
//设定low和high指针
int low = 0;
int high = a.length - 1;
while(low<=high){
int mid = low + (high-low)>>1;
if(a[mid]==value)
{
return mid;
}else if(a[mid]<value){
low = mid + 1;
}else{
high = mid - 1;
}
}
return -1;
}
二分查找递归算法
public int bSearch(int[]nums,int value,int low,int high){
if(low>high) return -1;
int mid = low + (high - low)>>1;
if(nums[mid]==value)
return mid;
else if(nums[mid]>value)
return bSerarch(nums,value,mid+1,high);
else
return bSearch(nums,value,low,mid-1);
}
代码分析:
a[mid]与要查找的value之间的关系就是:大于、小于、等于;
对于大于,只需要更新 high = mid - 1;
对于小于,只需要更新 low = mid +1;
当a[mid] = value的时候,需要判断是否是第一个值等于value:
//二分查找第一个值等于给定值的元素
public int bSearch(int[] nums,int value){
int low = 0;
int high = nums.length - 1;
while(low<=high){
int mid = low + ((high - low)>>1);
if(a[mid]>value)
high = mid - 1;
else if(a[mid]<value)
low = mid + 1;
else{
//判断mid-1是否等于value
if(mid == 0||a[mid-1]!=value)
return mid;
else{
high = mid - 1;
}
}
}
return -1;
}
类似于变体一,那我直接call 代码啦!
public int bSearch(int[]nums,int value){
int low = 0;
int high = nums.length - 1;
while(low <= high){
int mid = low + ((high-low)>>1);
if(a[mid]>value)
high = mid - 1;
else if(a[mid]<value)
low = mid + 1;
else{
if(mid==nums.length-1||a[mid]+1!=value)
return mid;
else
low = mid + 1;
}
}
return -1;
}
话不多说,直接code
public int bSearch(int[]nums,int value){
int low = 0;
iny high = nums.length - 1;
while(low<=high)
{
int mid = low + ((high-low)>>1);
if(a[mid]>=value)
{
if(mid==0||a[mid-1]<value)
return mid;
else{
high = mid - 1;
}
}
else{
` low = mid + 1;
}
}
return -1;
}
public int bSearch(int[]nums,int value)
{
int low = 0;
int high = nums.length - 1;
while(low<=high)
{
int mid = low +((high-mid)>>1);
if(a[mid]<=value)
{
if(mid==nums.length-1||a[mid]+1>value)
return mid;
else
low = mid + 1;
}else{
high = mid - 1;
}
}
return -1;
}
如何在1000万个整数中快速查找某个整数?
内存限制是100M,每个数据大小是8个字节,那么所有数据存储到数组中占据80M的内存,符合内存的限制,先对1000万个数据进行排序,然后再利用二分查找进行查找;