【演算法】跨越式搜尋之陣列查詢
阿新 • • 發佈:2019-01-22
題目1:給出一個一維陣列A, 大小為n, 相鄰元素的差的絕對值都為1. 如A = [1, 0, 1, 2, 3, 2, 1, 2, 3],現在給定A和目標查詢數num. 請找到num在陣列中的位置。
題目2:在題目一的前提下,現在要返回num的所有索引位置。
思路:依次遍歷可以實現,但是複雜度O(N).
如果陣列第一個元素是A[0], 要找的數是num. 設 t = abs(num - A[0]). 由於每個相鄰的數字之差的絕對值為1,所以在第t個位置之前的數字都肯定比num小。因此下次搜尋定位到A[t]。重新計算t, t = abs(num - A[t]),重複上面的步驟。利用了當前位置和查詢數字的差實現了跨越式搜尋。這種搜尋方法比遍歷陣列要高一些。
題目一和題目二其實是一個題,題目一找到元素後就返回,題目二要直到搜尋到陣列末尾。
AC Code:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <vector>
using namespace std;
int FindNumInArray(int arr[], int n, int num)
{
int NextIndex = abs(num - arr[0]);
while(NextIndex < n)
{
if(arr[NextIndex] == num)
return NextIndex;
NextIndex += abs(num - arr[NextIndex]);
}
return -1;
}
void FindAllNumInArray(int arr[], int n, int num, vector<int>& ret)
{
int NextIndex = abs(num - arr[0]);
while(NextIndex < n)
{
if(arr[NextIndex] == num)
{
ret.push_back(NextIndex);
++NextIndex;
}
else
{
NextIndex += abs(num - arr[NextIndex]);
}
}
return;
}
void main()
{
const int maxlen = 10;
int arr[maxlen] = {1,0,1,2,3,2,1,2,3,4};
//測試題目一,查詢第一個匹配的數的索引
printf("查詢%d, \t下標為%d, \t實際下標為0\n",1,FindNumInArray(arr, maxlen, 1));
printf("查詢%d, \t下標為%d, \t實際下標為4\n",3,FindNumInArray(arr, maxlen, 3));
printf("查詢%d, \t下標為%d, \t實際下標為9\n",4,FindNumInArray(arr, maxlen, 4));
printf("查詢%d, \t下標為%d, \t實際下標為-1\n",-1,FindNumInArray(arr, maxlen, -1));
//測試題目二,返回所有的索引
vector<int> ret;
FindAllNumInArray(arr, maxlen, 1, ret);
if(!ret.empty())
{
for(vector<int>::size_type i = 0; i < ret.size(); i++)
printf("查詢索引%d \t下標為%d", 1, ret[i]);
}
getchar();
return;
}
執行結果: