日志|寻找旋转排序数组中的最小值|寻找两个正序数组的中位数|二分查找

while (left < right) 用于寻找一个位置(如最小值点、边界),目的是让两个指针最终精确地汇合于答案点。
while (left <= right) 用于在一个确定的区间内查找一个特定的值,搜索会持续到区间被彻底检查完毕(区间为空)。
如果改为( <= ) :当 left 和 right 最终指向同一个元素(即最小值)时,因为 left == right,循环条件 left <= right 依然成立,会进入下一次循环
。
此时 mid = left + (right - left)/2 = left。
判断 nums[mid] <= nums[right](即 nums[left] <= nums[left]),条件成立,会执行 right = mid。
这导致 right 的值不变(right = left),然后循环继续,left 和 right 的值不再变化,从而产生无限循环。
点击查看代码
class Solution {
public int findMin(int[] nums) {
int left = 0 , right = nums.length - 1;
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid] > nums[right]){
left = mid + 1;
}
else if(nums[mid] <= nums[right]){
right = mid;
}
}
return nums[left];
}
}





点击查看代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//先交换最小数组在前
if(nums1.length >= nums2.length){
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
}
//
int m = nums1.length, n = nums2.length;
int l = 0, r = m;// 搜索分割点位置,共m+1种可能
while(l <= r){
int i = l + (r - l)/2 ;
int j = (m + n + 1)/2 - i;
//
int nums1Left = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];
int nums1Right = (i == m) ? Integer.MAX_VALUE : nums1[i];
int nums2Left = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];
int nums2Right = (j == n) ? Integer.MAX_VALUE : nums2[j];
//
if(nums1Left <= nums2Right && nums2Left <= nums1Right){
if((m+n) % 2 == 1){//总和为奇数,中位数就是i-1 和 j-1 的最大值
return Math.max(nums1Left,nums2Left);
}
else{//总和为偶数,中位数是 (i-1 和 j-1 的最大值)+ (i 和 j 的最小值) 整体除2
return (Math.max(nums1Left,nums2Left) + Math.min(nums1Right,nums2Right))/ 2.0;
}
}
else if(nums1Left > nums2Right){
r = i - 1;
}
else if(nums2Left >nums1Right){
l = i + 1;
}
}
// 循环结束后必须返回
throw new IllegalArgumentException("No solution found");
}
}
浙公网安备 33010602011771号