循环有序数组的查找笔记
来源:互联网 发布:java中interface 编辑:程序博客网 时间:2024/04/29 23:44
背景:
雷达方位角的初步定位.
方法:
定义
一个循环有序数组(如:3,4,5,6,7,8,9,0,1,2),不知道其最小值的位置,要查找任一数值的位置。要求算法时间复杂度为log2(n)。
对于循环有序数组,一种简单的定义是:
循环有序数组是将一个有序数组切成两段,并交换位置得到引用块内容
另一种比较严格的定义是:
对于一个循环有序数组
a1,a2,…,an ,存在一个i,满足1< i < n,使得a1,a2,…,ai 和ai,ai+1,…,an 同为单调不减,或单调不增数组。且a1,a2,…,ai 中的任意一个元素恒大与等于或恒小于等于ai,ai+1,…,an 中的任意一个元素。
性质:
1.将一个循环有序数组一分为二,一定得到一个有序数组和另一个循环有序数组
2.长度不超过2的循环有序数组其实就是有序数组。
解答思路:
第一步:我们要先弄清楚这个循环有序数组的原数组是单调减的还是单调增,如果
a1>an ,那么a一定是增加型的循环有序数组,如果a1<an ,那么a一定是减少型的循环有序数组。注意:
a1=an 这种情况。第二步:判断左边一半和右边一半哪一个是有序的。这里以增加型的举例,减少型的同理。如果a[mid] >= a[start],那么左边一定是有序的。因为如果左边是循环有序的,那么最大值点一定出现在左侧,且最大值点左侧的数恒大于最大值点右侧的数。这与a[mid] >= a[start]矛盾。反之同理。
第三步:确定了有序的一侧后,就要判断是不是在这一侧搜索了。这个判断非常简单,只要确定待搜索的数的值是否在有序数列的两个端点值之间即可。
第四步:最后通过循环,就可以类似二分法,找到待搜索的数的位置。
代码
注:
#include <iostream>using namespace std;int getIndex(int a[],int seek,int arrayLength){ int start = 0; int end = arrayLength; if (a[start] >= a[end]) {//单增 while (start <= end) { int mid = start + (end - start)/2; int midValue = a[mid]; //说明这是一个在增加的循环有序数组 if (midValue >= a[start]) { //左侧单调递增 if (seek == a[mid]) { return mid; } else if (seek < a[mid] && seek >= a[start]){ //一定是在左侧查找 end = mid - 1; }else{ //在右侧查找 start = mid + 1; } } else{ //右侧单调递增,同理 if (seek == a[mid]) { return mid; } else if (seek > a[mid] && seek <= a[end]){ //一定是在右侧查找 start = mid + 1; } else{ //在左侧查找 end = mid - 1; } } }// while end //没找到元素 return -1; } else{ while (start <= end) { int mid = start + (end - start)/2; int midValue = a[mid]; //说明这是一个在减少的循环有序数组 if (midValue >= a[start]) { //右侧单调递减 if (seek == a[mid]) { return mid; } else if (seek < a[mid] && seek >= a[end]){ //一定是在右侧查找 start = mid + 1; } else{ //在右侧查找 end = mid - 1; } } else{ //左侧单调递减,同理 if (seek == a[mid]) { return mid; } else if (seek <= a[start] && seek > a[mid]){ //一定是在左侧查找 end = mid - 1; } else{ //在左侧查找 start = mid + 1; } } } //没找到元素 return -1; }}int main(int argc,char * argv[]) {// int a[] = {12,16,18,20,41,100,1,4,6,9}; int a[] = {9,6,4,1,100,41,20,18,16,12}; int seek = 20; int arrayLength = sizeof(a)/sizeof(a[0]) - 1; int index = getIndex(a,seek,arrayLength); index == -1 ? cout<<"not found" : cout<<index; return 0;}
- 循环有序数组的查找笔记
- 循环有序数组的查找
- 循环有序数组查找
- 有序 循环数组的二分查找
- 查找循环有序数组的元素
- 循环有序数组查找问题
- 循环有序数组查找值
- 二分数组的扩展:二分查找循环有序数组
- 循环有序数组/旋转数组的二分查找
- 在一个循环有序的数组里查找特定值
- 【百度面试题】循环有序数组的查找问题
- 【百度面试题】循环有序数组的查找问题
- 【百度面试题】循环有序数组的查找问题
- 有序数组的查找
- 有序数组的查找
- 循环有序数组查找一个数
- 循环有序数组中查找指定值
- 有序数组的随机化查找
- how to display Error message including Html tag in apex trigger
- arch-问题
- Mybatis循环处理 like
- html(二)页面中图片及多媒体的简单处理
- Android 自定义日期和时间和星期的弹窗
- 循环有序数组的查找笔记
- 兄弟选择器——用于选择除第一个元素外的其他兄弟元素
- android studio 安装插件的方法
- 1月4日记录(二):新网站收录好像还很不错
- andoroid的ListView优化以及如何跳转到第一页
- arch-yaourt安装
- Android ADB常用命令
- 电动车无刷电机控制器软件设计要点(整理)
- 工厂三兄弟之抽象工厂模式(二):产品等级结构与产品族