题目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;
}
运行结果: