循环有序数组中最小元素的查找(二分查找)

问题描述:

如题,其中循环有序数组指的是对有序数组进行循环移位后的结果,如[7,8,9,0,1,2,3,4,5,6];

实现思路:

由循环有序数组结构可知,若数组不为整体有序,则最小值一定是处于无序子序列之中,如上述例子中,最小值一定处于7到1之间,而一定不处于1到6之间,根据该性质可以得到如下算法:

先进行判断该数组是否整体有序(arr[left] < arr[right]),若有序返回left即可。

对于整体无序情况(arr[left] < arr[right]),mid = left + (right - left) / 2,判断left - mid 和 mid - right是否为有序,

若arr[mid] > arr[right] 对mid - right部分进行查找,arr[mid] < arr[left] 对left - mid 部分进行查找.;

若以上条件均不满足即(arr[mid] <= arr[right] && arr[mid] >= arr[left]),又由于arr[left] >=arr[right] 所以可得:

arr[mid] = arr[left] = arr[right],对于该情况只能采用从头到尾的方式进行搜索了。

具体实现代码如下:

     public static int selution(int[] arr) {
         int left = 0, right = arr.length - 1, mid = 0;
         while (right - left > 1) {
             if (arr[left] < arr[right]) {
                 return left;
             }
             mid = left + (right - left) / 2;
             // arr[left] >= arr[right]
             if (arr[mid] < arr[left]) { //最小值在左端
                 right = mid;
             }
             if (arr[mid] > arr[right]) { //最小值在后面
                 left = mid;
             }
             if (arr[mid] >= arr[left] && arr[mid] <= arr[right]) {
                 //即 arr[right] = arr[left] = arr[mid]
                 return findMin(arr, left, right);
             }
         }
         return  arr[left] < arr[right] ? left : right;// 返回left right 中最小的
     }
     public static int findMin(int[] arr, int left, int right){
         int minIndex = left ,min = arr[left];
         for (int i = left + 1; i <= right; i++) {
             if(arr[i] < min) {
                 min = arr[i];
                 minIndex = i;
             }
         }
         return minIndex;
     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值