1. 程式人生 > >【演算法】跨越式搜尋之陣列查詢

【演算法】跨越式搜尋之陣列查詢

題目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; }

執行結果:
這裡寫圖片描述