【算法】跨越式搜索之数组查找

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

运行结果:

时间: 2024-08-05 01:23:28

【算法】跨越式搜索之数组查找的相关文章

《剑指Offer》算法题——二维数组查找

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. class Solution { public: bool Find(vector<vector<int> > array, int target) { int col = array.size(); int i = 0; while (i < col) { int j = array[i].size()

KT学算法(二)——循环有序数组查找指定元素

问题描述 一个循环有序的数组是形如:"12,16,18,20,41,100,1,4,6,9" 这样的数组. 问题分析 对于循环有序数组,一种简单的定义是: 循环有序数组是将一个有序数组切成两段,并交换位置得到引用块内容 比如现将1,4,6,9,12,16,18,20,41,100在9和12处切分,得到两段:1,4,6,9和12,16,18,20,41,100,再交换这两段的位置就得到了一开始的循环有序数组. 另一种比较严格的定义是: 对于一个循环有序数组{A1,A2,--An},存在一

小橙书阅读指南(十二)——无向图、深度优先搜索和路径查找算法

在计算机应用中,我们把一系列相连接的节点组成的数据结构,叫做图.今天我们将要介绍它的一种形式--无向图,以及针对这种结构的深度优先搜索和路径查找算法. 一.无向图数据结构 接口: /** * 图论接口 */ public interface Graph { /** * 顶点数 * * @return */ int vertexNum(); /** * 边数 * * @return */ int edgeNum(); /** * 向图中添加一条v-w的边 * * @param v * @param

蓝桥杯 算法训练 ALGO-50 数组查找及替换

算法训练 数组查找及替换 时间限制:1.0s   内存限制:512.0MB 问题描述 给定某整数数组和某一整数b.要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序.如果数组元素数值在A到Z的ASCII之间,替换为对应字母.元素个数不超过100,b在1至100之间. 输入格式 第一行为数组元素个数和整数b 第二行为数组各个元素 输出格式 按照要求输出 样例输入 7 2 77 11 66 22 44 33 55 样例输出 11 33 55 M 示例代码: 1 #include<

算法开篇学习之数组元素查找

[摘要]最近两个月都在学习 Linux 驱动,中间碰到了很多问题,进度比较缓慢.尽管不是班科出生的,但是还是觉得算法很有必要学一学.因此将数组元素查找作为自己算法开篇的第一篇博客,好好跟着平凡程序员的博客学习,内容基本是拿来主义. 我们可以下面一个数组查找的函数说起.一句一句写起,首先我们开始从最简单的函数构造开始 int find(int array[], int length, int value) { int index = 0; return index; } 这里看到,查找函数只是一个

算法训练——数组查找及替换

//数组查找及替换 #include<stdio.h> #include<stdlib.h> int comp(const void *a,const void *b){ return *(int*)a - *(int*)b; } int main(){ int N,b; int a[101]; scanf("%d%d",&N,&b); for(int i=0;i<N;i++) scanf("%d",&a[i])

十大基础实用算法之归并排序和二分查找

归并排序 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 算法步骤: 1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置 3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 4. 重复步骤3直到某一指针达到序列尾 5. 将另一序列剩下的所有元素直接复制到合并序列尾 用分治策略解决问题分为三步:分解

算法复习笔记:二分查找

在计算机科学中,折半搜索(英语:half-interval search),也称二分查找算法(binary search).二分搜索法.二分搜索.二分探索,是一种在有序数组中查找某一特定元素的搜索算法.搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半. 实现: int bin

算法题:求数组中最小的k个数

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:输入n个整数,找出其中最小的k个数. <剑指offer>给出了两种实现算法: 算法1:采用Partition+递归法,该算法可以说是快速排序和二分查找的有机结合.算法的时间复杂度为O(n),缺点在于在修改Partition的过程中会修改原数组的值. 算法2:采用top-k算法.如果要找最小的K个数,我们才用一个含有K个值的大顶堆:如果要找最大的K个数,我们采用小顶堆.该算法的时间复杂度为O(nlogK),是一种比较好的算法,启发于堆排序