解法都在代码里,不懂就留言或者私信
class Solution {
/**题目给的数据的一个重要性质要把握:无重复数,这就好办了
其实旋转数组系列题最主要的点在于如何找到旋转点的位置,旋转之后的数组有啥特性:一半仍然是有序的(非旋转部分),另外一半先变小后变大(旋转部分)
我们每次把数组进行二分,如果中间位置的值比左边大,说明左边整体有序,旋转点在右边,否则旋转点在左边 */
public int findMin(int[] nums) {
/**就一个数,旋转不旋转都是你自己 */
if(nums.length == 1) {
return nums[0];
}
/**大于两个数就得找找了,你要是高兴再写个nums.length==2比较nums[0]和nums[1]也行 */
/**我这里就进行通用的比较了,不管多少个数了 */
int left = 0;
int right = nums.length - 1;
/**用一个遍历记录以下结果值 */
int ans = Integer.MAX_VALUE;
while(left <= right) {
/**位运算纯属得瑟,你可以写成(right-left)/2 */
int mid = left + ((right - left) >> 1);
/**如果mid位置比left位置大,说明left~mid整体有序,注意这里写大于等于,虽然题目规定所有数都是不同的,但是mid和left可能是同一个位置*/
if(nums[mid] >= nums[left]) {
/**最小值如果出现在这个区域就是left位置的值*/
ans = Math.min(ans, nums[left]);
left = mid + 1;
} else {
/**如果mid比left位置的小,说明左边出现了旋转,右边mid~right是整体有序的
但是这里我们就不需要判断它出现在左边还是右边了,既然左边发生了旋转,那一定出现在左边
这里写right=mid,而不是mid-1是因为可能mid就是旋转点,如果写成mid-1就刚好把它错过了
其实和if里写成类似的ans = Math.min(ans, nums[mid])也行,这样就可以写right = mid - 1
*/
ans = Math.min(ans, nums[mid]);
right = mid -1;
}
}
return ans;
}
}
执行结果