当前位置:网站首页>给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。【剑指Offer】
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。【剑指Offer】
2022-07-03 00:59:00 【小型骷髅】
先贴代码:
class Solution {
public int minArray(int[] numbers) {
int left = 0; // 定义左指针
int right = numbers.length-1; // 定义右指针
if (right == 0){
return numbers[0];
}
while (left < right){
int mid = left + (right - left) / 2; // 定义中间指针
if (numbers[mid] > numbers[right]){ // 若中间值大于最右边值时,说明分界点在mid右边
left = mid + 1;
}else if (numbers[mid] < numbers[right]){ // 若中间值小于最右边,则分界点在mid左边
right = mid;
}else if (numbers[mid] == numbers[right]){ // 若中间值等于左右边,则暴力缩小范围
right--;
}
}
return numbers[left];
}
}
解题思路:
题目当中给了我们一个旋转后的,并且可能存在重复元素的数组 numbers ,要求求出这个数组的最小值。
如果不考虑这个数组的特殊性,仅仅是找出数组里的最小值,相信大家都知道先遍历数组,将前一个元素和后一个元素进行比较,直到遍历完数组找到最小值。或者先将数组排序,直接输出数组的第一个元素。
这些都是一些初级的写法,如果题目考的是这些的话,那么就根本不会弄出这个旋转后一次并且可能存在重复元素的数组的。所以要想高效的解题,就必须从这个特殊的数组入手。那么我们先来看看,什么是经过一次 “旋转” 后的数组。
“把一个数组开始的若干元素搬到数组的末尾”,这个做法称为数组的“旋转”。例如数组【1,2,3,4,5】经过旋转后变为了【4,5,1,2,3】:
由题意得,数组开始旋转之前是一个升序数组,那么我们就可以得出,一个数组经过一次旋转后,是由两个升序数组拼接而成的。也就是说,这个新数组,是由两个升序数组相组合而成。
那么这时候,就可以使用二分查找,来找出这个新数组的最小值。那现在就有疑问了,二分查找不是适用于一个有序的数组吗?这两个有序数组组合在一起,也适用吗?
我们来看看,二分法究竟适不适用于刚才的情况。由上图可知,旋转后的数组是由前面若干个元素搬到后面,所以最小的元素一定是后一个有序数组的第一个元素,即为后一个有序数组和前一个有序数组想接触的地方,称为分界点!所以相应的,我们一旦找到分界点,也就找到了最小值。那么分界点又该怎么找呢?
我们先设定数组的左右边界 left 和 right ,并且找到中间位置,设为 mid ,那么就有:
当 mid 小于 right 时,说明什么?说明从 mid 开始 往后直到 right ,都是一个升序的有序数组,那么分界点有可能在 mid 右边吗?不可能!所以想找到分界点,只能在 mid 右边找。那么上面数组就变成了:
现在再来判断,当 mid dayu right 时,这时候说明什么?说明从 mid 开始 到 right ,中间是有一个断层的,那么这个断层就是我们要找的分界点!所以令左边界 left 变为 mid + 1 。
当 left 和 right 都指向同一个值时,表示找到了分界点,进而就表示找到了数组的最小值。这时候我们再回过头来分析,我们刚刚解析问题,找出分界点的方法是不是就是二分查找法?
可是以上过程我们忽略了一个问题,就是题目说明了数组中是可能存在重复元素的,那么当出现重复元素时,以上分析还奏效吗?显然已经不奏效了!因为当 mid 和 right 和 left 的值都相等时,就无法判断究竟是 mid 左边是有序数组还是 mid 右边 是有序数组了。这时候应该怎么呢?如下图所示:
现在 mid、left、right 都是一样的值,根本判断不了谁是有序的,那么我们现在只能手动缩小范围,将 right 往右移动一位,即 right -- !这样,就变成了:
这时候就可以判断了!
边栏推荐
猜你喜欢
随机推荐
(C language) data storage
Strongly connected components of digraph
Specified interval inversion in the linked list
Database SQL language 02 connection query
Matlab Doppler effect produces vibration signal and processing
[shutter] image component (configure local GIF image resources | load placeholder with local resources)
Understanding and distinguishing of some noun concepts in adjustment / filtering
Several cases of recursive processing organization
Appuyez sur l'apprentissage de l'esprit de frappe - reconnaissance des coordonnées de fond multithreadées
鏈錶內指定區間反轉
Cut point of undirected graph
MySQL
1696C. Fishingprince plays with array [thinking questions + intermediate state + optimized storage]
Meibeer company is called "Manhattan Project", and its product name is related to the atomic bomb, which has caused dissatisfaction among Japanese netizens
Basic remote connection tool xshell
The difference between relational database and non relational database
MongoDB系列之MongoDB常用命令
[Arduino experiment 17 L298N motor drive module]
Button wizard play strange learning - go back to the city to buy medicine and add blood
如今少年已归来,人间烟火气最抚凡人心 复工了~