算法整理-二分查找和排序

博客介绍了二分查找在不同场景的应用。包括在有序数组中查找插入位置,判断终止条件,若查找不到返回begin;在不包含重复数字的rotated array中寻找最小值;在允许重复的rotated array中寻找某个值,分递增数组、特定相等情况及两段数组类型进行处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  二分查找

   (1) 有序数组查找插入位置:  主要是终止条件的判断,如果查找不到需要被范围的插入位置为begin

public:
    int searchInsert(vector<int>& nums, int target) {
        int len = nums.size();
        return binarySearch(nums, target, 0, len-1);
    }
private:
    int binarySearch(vector<int>& nums, int target, int begin, int end) { if (begin > end) { return begin; } int mid = (begin + end) / 2; if (target == nums[mid]) return mid; else if (target < nums[mid]) { return binarySearch(nums, target, begin, mid - 1);} else { return binarySearch(nums, target, mid+1, end);} }

  (2) rotated array 寻找最小值

      第一种情况: 不包含重复数字, 

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len = nums.size();
        return bsearch(nums, 0, len-1);        
    }
private: int bsearch(const vector<int> nums, int s, int e){ if (s >= e) return nums[s]; int mid = (s + e) / 2;
// 在左侧数组上 if (nums[mid] > nums[e]) return bsearch(nums, mid+1, e);
// 在右侧数组上 else return bsearch(nums, s, mid); } };

   (3) rotated array 寻找某个值,允许重复:

         分成三种情况,(1) 是递增数组 (2) num[s] == num[mid] = nums[e]    用O(n)的时间顺序查找

                              (3)两段数组的类型, 二分查找,先判断mid是在哪一段数组上

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int len = nums.size();
        if(len == 0) return false;
        return bsearch(nums, target, 0, len - 1); } private: bool bsearch(const vector<int>& nums, int target, int s, int e){ if ( s > e) { return false; } if (cornercase(nums, s, e)){ return asearch(nums, target, s, e); } if (nums[s] >= nums[e]){ int mid = (s + e) / 2; if (nums[mid] == target) return true; if (nums[mid] >= nums[s]) { // mid在左边序列 // target比mid大一定在右边序列 if (target > nums[mid]) return bsearch(nums, target, mid+1, e); // t比mid小,当t大于end则一定在左侧 else if (target > nums[e]) return bsearch(nums, target, s, mid-1); else if (target < nums[e]) return bsearch(nums, target, mid+1, e); else return true; } if (nums[mid] < nums[s]) {// mid在右边序列 if (target < nums[mid]) return bsearch(nums, target, s, mid-1); else if(target > nums[e]) return bsearch(nums, target, s, mid-1); else if(target < nums[e]) return bsearch(nums, target, mid+1, e); else return true; } } return false; } bool cornercase(const vector<int>& nums, int s, int e){ int mid = (s + e) / 2; if (nums[s] == nums[e] && nums[mid] == nums[s]){ return true; } if (nums[s] <= nums[e] && nums[mid] >= nums[s]){ return true; } return false; } bool asearch(const vector<int>& nums, int target, int s, int e){ for (int i = s; i <=e; i++){ if (nums[i] == target) return true; } return false; } };

 

转载于:https://www.cnblogs.com/cookcoder-mr/p/11080055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值