题目
7-2
设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
输入格式:
输入有两行:
第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。
输出格式:
输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。当搜索元素在数组中时,i和j相同。 提示:若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值
输入样例:
在这里给出一组输入。例如:
6 5
2 4 6 8 10 12
输出样例:
在这里给出相应的输出。例如:
1 2
算法描述这道题是在二分查找的基础上实现的,首先应判断输入的x是否大于或小于有序数组中所有的数,如果是则给出题目要求的输出,并退出程序;如果不是则进行二分查找,有两种结果:一是数组存在X,则返回X所在下标; 二是数组中不存在X,此时right在左,left在右,两者分别是小于x的最大元素的最大下标和大于x的最小元素的最小下标。代码如下:
#include <iostream> using namespace std; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char** argv) { int num; cin>>num; int aim; cin>>aim; int a[num]; for(int i=0;i<num;i++) { cin>>a[i]; } int left=0; int n=-1; int result=-1; int right=num-1; if(aim<a[0]) { cout<<"-1 0"; return 0; } if(aim>a[num-1]) { cout<<num-1<<" "; cout<<num; return 0; } while(left<=right) { int mid=(left+right)/2; if(aim==a[mid]) { n= mid; break; } if(aim>a[mid]) left=mid+1; else right=mid-1; result=mid; } if(n!=-1) { cout<<n<<" "; cout<<n; } else { cout<<right<<" "; cout<<left; } return 0; }
算法时间及空间复杂度分析:最好时间复杂度是O(1),即输入的x大于或小于有序数组中所有的数;
若数组存在X,则平均时间复杂度为 O(logn);
最坏时间复杂度为O(logn)+1,即有序数组中不存在X;
空间复杂度为O(3)
心得体会:不要着急做题,要看清题目要求,尽量第一次就详细的分析,比如一开始我只判断了输入的数小于数组第一个数要输出什么,忽略了设置如果大于最大数的输出
原文地址:https://www.cnblogs.com/Li-Peiting/p/9782713.html
时间: 2024-10-04 02:29:56