旋转数组的查找问题

题目:一个数组是由一个递增数列右移若干位形成的,比如{4,5,1,2,3}是由{1,2,3,4,5}左移两位形成的,在这种数组中查找某一个数。

解题思路如下:

首先获取元素分裂点,时间复杂度为O(log(n))

因为旋转数组是由递增数组右移得到,因此旋转数组中的第一个元素是整个数组的中间元素,比较待查找元素与第一个元素,如果待查找元素大于等于第一个元素,表明待查找元素在前半段有序数组中;如果不是这待查找元素在后半段数组中。

判断待查找元素所在的有序数组以后,我们通过一个简单的二分查找就可以找出元素所在位置,时间复杂度也是O(log(n))

总是时间复杂度为2个O(log(n)),所以时间复杂度还是O(log(n))。

#include<iostream>
#include<stdlib.h>
#include<stack>
#include<cassert>
using namespace std;

//函数声明
int getSplitIndex(int arry[],int len);//获取分裂点坐标
int BinarySearch(int arry[],int len,int value);//二分查找通用算法
int FindNumInRotatedArry(int arry[],int len,int value);//查询元素位置

//二分查找算法,不使用递归,如果存在返回数组位置,不存在则返回-1
int BinarySearch(int arry[],int start,int end,int value)
{
    //如果传入的数组为空或者数组长度<=0那么就返回-1。防御性编程
    if(arry==NULL||start>end)
        return -1;

    while(start<=end)//判断清是否有=
    {
        int mid=start+(end-start)/2;
        if(arry[mid]==value)
            return mid;
        else if(value<arry[mid])
            end=mid-1;
        else
            start=mid+1;
    }
    return -1;

}

int getSplitIndex(int arry[],int len)//返回最小数的坐标
{
    if(arry==NULL||len<=0)
        return -1;

    int start=0;
    int end=len-1;
    while(start<end)
    {
        //如果首个元素小于最后一个元素,表明数组是排序的。
        if(arry[start]<arry[end])
            return start;

        //当start指针和end指针隔壁的时候,返回end指针就是最小元素的坐标
        if(end-start==1)
            return end;

        int mid=(start+end)/2;
        //如果arry[mid],arry[start]和arry[end]三个数相等,就只能使用顺序查找
        if(arry[mid]==arry[start]&&arry[mid]==arry[end])
        {
            int index=start;
            for(int i=start+1;i<=end;i++)
            {
                if(arry[i]<arry[index])
                    index=i;
            }
            return index;
        }
        //如果中间元素小于末尾元素,那么表明中间元素在后半段数组中,修改end指针
        if(arry[mid]<arry[end])
        {
            end=mid;
        }
        //如果中间元素大于首元素,那么表明中间元素在前半段数组中,修改start指针
        else if(arry[mid]>arry[start])
        {
            start=mid;
        }
    }
    return -1;
}

int FindNumInRotatedArry(int arry[],int len,int value)//返回最小数的坐标
{
    if(arry==NULL||len<=0)
        return -1;

    int start=0;
    int end=len-1;

    int splitIndex=getSplitIndex(arry,len);//获取分裂点坐标
    cout<<"分裂点坐标:"<<splitIndex<<endl;
    //比较待查找元素与第一个元素的大小,如果大于等于第一个元素表明待查找元素在前半段
    if(value>=arry[start])
    {
        end=splitIndex-1;
        return BinarySearch(arry,start,end,value);
    }
    else//否则在后半段查找
    {
        start=splitIndex;
        return BinarySearch(arry,start,end,value);
    }
    return -1;
}

void main()
{
    int arry[]={4,5,1,2,3};

    int len=sizeof(arry)/sizeof(int);

    int value=3;
    int index=FindNumInRotatedArry(arry,len,value);
    cout<<"查找数在数组中的位置:"<<index<<endl;

    system("pause");
}
时间: 2024-10-16 02:41:57

旋转数组的查找问题的相关文章

旋转数组中查找指定元素

如题,在旋转数组中查找指定元素,考虑到多种情况,网上的方法大部分没有考虑,当low,high,mid三个值相等时的情况. 代码如下: int findAll(int A[],int low,int high,int value)//当三个相等时,查找全部元素的函数. { for(int i = low;i < high;i++) { if(A[i]==value) return i; } return -1; } int find(int A[],int n,int value)//查找旋转数组

程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】

转!http://blog.csdn.net/dabusideqiang/article/details/38271661 11.求旋转数组的最小数字 题目:输入一个排好序的数组的一个旋转,输出旋转数组的最小元素. 分析:数组的旋转:把一个数组最开始的若干个元素搬到数组的末尾.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组

旋转数组中查找最小值-剑指Offer11

1.题目简介 求一个旋转数组的最小值.( 把一个数组从最开始的若干个元素搬到数组的末尾,即为旋转数组.) 输入:一个递增排序数组的旋转 输出:数组的最小值 例子:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 2.思路分析 最直观的解法是从头到尾顺序遍历,这种方法的时间复杂度为O(n).这里并没有用到旋转数组的知识,显然不合题意. 结合提议,旋转数组从有序数组中的得来的,经过旋转后得到的两个部分也为有序的.在有序数组中查找首选二分法,可以把时间复杂度变为O(n

leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法

Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise retu

旋转数组的查找-经典

https://leetcode.com/problems/search-in-rotated-sorted-array/?tab=Description 很好的很经典的题目.今天复习了一下.之前的思路虽然有了,但是对于相等的数字的处理很复杂,容易出错.今天看到了一个很好的解法. https://discuss.leetcode.com/topic/3538/concise-o-log-n-binary-search-solution 思路是先找出最小的数字的下标,通过 mid > hi,就lo

求旋转有序数组的最小值和在旋转数组中查找

#include<iostream> using namespace std; int find2(int A[],int n) { int high=n-1; int low =0; int mid; while(A[high]<=A[low]) { if(high-low==1) { mid=high; break; } mid=low+(high-low)/2; if(A[mid]>=A[low]) { low=mid; }else if(A[mid]<=A[high]

[Leetcode] 旋转问题(旋转数组的查找,旋转list,旋转矩阵)

[1] Search in Rotated Sorted Array [2] Search in Rotated Sorted Array II [3] Find Minimum in Rotated Sorted Array [4] Find Minimum in Rotated Sorted Array II [5] Rotate Array [6] Rotate List [7] Rotate Image 一.

剑指offer面试题8——旋转数组的最小数字

题目1386:旋转数组的最小数字 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6708 解决:1505 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n

题目八:旋转数组的最小数字

///////////////////////////////////////////////////////////////////////////////////////////// //12. 题目八:旋转数组的最小数字 int RotatedBinarySearchMinNum(int aiArray[], int iLen) { int iLeft = 0; int iMid = 0; int iRight = iLen - 1; while (aiArray[iLeft] >= ai