C算法-二分查找

leetcode34题,在排序数组中查找元素的第一个和最后一个位置。
leetcode875题,爱吃香蕉的珂珂。注意坑:1、不要对大数求和再做除法。2、单独考虑如果值为1的情况;3、考虑越界情况!!4、逻辑运算符坑太多,最好用if else

这个作者写的确实蛮好的,提供了一些思路,我主要讲一下如何消化的吧。
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/

有三种需求:
1、搜索某个有序序列是否存在某个数
2、搜索某个有序序列存在某个数的左区间
3、搜索某个有序序列存在某个数的右区间

抄一下作者,因为左闭右闭比较好记忆不出错,应试教育还是一切从简。
1、用[left,right]来表示搜索区间
2、那么搜索区间不为空的情况是left <=right

3、如果当前a[mid]<target,那么对left=mid+1,保证当前left可能满足 = target
4、如果当前a[mid]>target,那么对right=mid-1,保证当前right可能满足 = target
5、如果当前a[mid]=target,
对情况1,已经找到,可以结束
对情况2,right=mid-1,做一个逼近用;此时right很有可能不会满足=target了,且一旦发生right再也没资格移动了,left即为所求。left可能被+1到越界。
对情况3,left=mid+1,做一个逼近用;此时left很有可能不会满足=target了,且一旦发生left再也没资格移动了,right即为所有。right可能被-1到越界。

对比左闭右开的情况。
1、用[left,right)来表示搜索区间
2、那么搜索区间不为空的情况是left <right;一旦left =right了,这个区间已空
3、如果当前a[mid]<target,那么对left=mid+1,保证当前left可能满足 = target
4、如果当前a[mid]>target,那么对right=mid-1,保证当前right可能满足 = target
5、如果当前a[mid]=target,
对情况1,已经找到,可以结束
对情况2,right=mid,代表当前这个mid已经被排除在搜索区间了;left/right即为所求。left可能被+1到越界。
对情况3,left=mid+1,代表当前这个mid已经被排除在搜索区间了;此时left/right-1即为所求。right可能到0即为越界。

int binary_search(int[] nums, int target) {
    
    
    int left = 0, right = nums.length - 1; 
    while(left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1; 
        } else if(nums[mid] == target) {
    
    
            // 直接返回
            return mid;
        }
    }
    // 直接返回
    return -1;
}

int left_bound(int[] nums, int target) {
    
    
    int left = 0, right = nums.length - 1;
    while (left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1;
        } else if (nums[mid] == target) {
    
    
            // 别返回,收缩左侧边界
            right = mid - 1;
        }
    }
    // 最后要检查 left 越界的情况
    if (left >= nums.length || nums[left] != target)
        return -1;
    return left;
}


int right_bound(int[] nums, int target) {
    
    
    int left = 0, right = nums.length - 1;
    while (left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1;
        } else if (nums[mid] == target) {
    
    
            // 别返回,收缩右侧边界
            left = mid + 1;
        }
    }
    // 最后要检查 right 越界的情况
    if (right < 0 || nums[right] != target)
        return -1;
    return right;
}

作者:labuladong
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

875题答案

bool CheckResult(int mid, int *piles, int pileSize, int H){
    
    
    int i, retsum;
    retsum = 0;
    for (i = 0; i < pileSize; i++) {
    
    
        if(piles[i] % mid){
    
    
            retsum = retsum + piles[i] / mid + 1;
        } else {
    
    
            retsum = retsum + piles[i] / mid;
        }
        if (retsum > H) {
    
    
            return false;
        }
    }
    return true;
}

int minEatingSpeed(int* piles, int pilesSize, int H){
    
    
    int i, min = 0, mid, max, mmax = 0;
    if (pilesSize == 1){
    
    
        if (piles[0] % H) {
    
    
            return piles[0] / H + 1;
        } else {
    
    
            return piles[0] / H;
        }
    }
    max = mmax;
    while(min <= max){
    
    
        mid = (min + max) / 2;
        if (CheckResult(mid, piles, pilesSize, H) == 1){
    
    
            max = mid - 1;
        }else {
    
    
            min = mid + 1;
        }
    }
    min = min > mmax ? mmax : min;
    return min;
}

自己作死,理解的左闭右开写出的答案

int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    
    
	int start, end, i, mid, okflag = 0;
	start = 0;
	end = numsSize;
	*returnSize = 2;
	int *res = (int *)malloc(sizeof(int) * 2);
	while (start < end) {
    
    
		i = (start + end) / 2;
		if (nums[i] < target) {
    
    
			start = i + 1;
		}
		else if (nums[i] > target) {
    
    
			end = i - 1;
		}
		else {
    
    
			end = i;
		}
	}
	if (numsSize == 0 || start >= numsSize) {
    
    
		res[0] = -1;
		res[1] = -1;
		return res;
	}
	if (nums[start] != target) {
    
    
		res[0] = -1;
		res[1] = -1;
		return res;
	}


	res[0] = start;
	start = end;
	end = numsSize;
	while (start < end) {
    
    
		i = (start + end) / 2;
		if (nums[i] > target) {
    
    
			end = i;
		}
		else {
    
    
			start = i + 1;
		}
	}


	res[1] = start - 1;
	return res;

}

猜你喜欢

转载自blog.csdn.net/weixin_45554139/article/details/104622572
今日推荐