c语言闯算法--数组二分

记住一点,左闭右闭(前提数组有序)

  1. 左右边界,取得到
  2. 循环范围可以等
  3. 中点计算防越界

二分找位置

二分查找(目标值一定存在)

int search(int* nums, int numsSize, int target) {
    int l = 0; int r = numsSize - 1;

    int middle = 0;

    while(l <= r){
        middle = l + ((r - l) / 2);
        int x = nums[middle];

        if(x < target){
            l = middle + 1;
        }else if(x > target){
            r = middle - 1;
        }else{
            return middle;
        }
    }

    return -1;
}

搜索插入位置(目标值不一定存在)

int searchInsert(int* nums, int numsSize, int target) {

    int l = 0; int r = numsSize - 1;

    int mid = 0;

    while(l <= r){
        mid = l + ((r - l) / 2);
        int x = nums[mid];

        if(x < target){
            l = mid + 1;
        }else if(x > target){
            r = mid - 1;
        }else{
            return mid;
        }
    }

    //最终没找到,模拟在l点
    return l;
    
}

寻找首末位置(存在,且不止一个)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
//注意:匹配到时,跟着走!!!!
int getL(int* nums, int numsSize, int target){
    int l = 0; int r = numsSize - 1;
    int mid = 0;

    int left = -2;//不变则不存在

    while(l <= r){
        mid = l + ((r - l) / 2);
        int x = nums[mid];

        //找左边界,让边界跟着右指针一直走
        if(x < target){
            l = mid + 1;
        }else{
            r = mid - 1;
            left = r;
        }
    }

    return left;
}

int getR(int* nums, int numsSize, int target){
    int l = 0; int r = numsSize - 1;
    int mid = 0;

    int right = -2;//不变则不存在

    while(l <= r){
        mid = l + ((r - l) / 2);
        int x = nums[mid];

        //找右边界,让边界跟着左指针一直走
        if(x <= target){
            l = mid + 1;
            right = l;
        }else{
            r = mid - 1;
        }
    }

    return right;
}

int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    //有返回,先定义
    int* res = malloc(2 * sizeof(int));
    *returnSize = 2;
    
    //分开找
    int l = getL(nums, numsSize, target);
    int r = getR(nums, numsSize, target);

    if(l == -2 || r == -2 || r - l == 1){
        //对应三种情况
        //1. 不存在,比最小值还小  2.不存在,比最大值还大 3.不存在,在数组中间
        res[0] = -1;
        res[1] = -1;
        return res;
    }

    //存在
    res[0] = l + 1;
    res[1] = r - 1;

    return res;
}

二分找算术根

x的平方根

int mySqrt(int x) {

    //解决特殊情况(1)
    if(x == 1){
        return 1;
    }

    //二分枚举
    int l = 0; int r = x / 2;
    long mid = 0;//避免爆内存

    while(l <= r){
        mid = l + ((r - l) / 2);
        long tmp = mid * mid;//避免爆内存

        if(tmp < x){
            l = mid + 1;
        }else if(tmp > x){
            r = mid - 1;
        }else{
            return mid;
        }
    }
    
    return l - 1;
}

x的三次方根

#include
#include
#include

int main(){
    double n;
    scanf("%lf", &n);
    
    double l = -10000; double r = 10000;//根据题目数据范围而设定
    double mid = 0;
    
    // while(l <= r){
    while((r - l) >= 1e-9){//浮点数,判断方式不同
        mid = l + ((r - l) / 2);
        
        double x = mid * mid * mid;
        
        if(x < n){
            l = mid;
        }else if(x > n){
            r = mid;
        }else{
            printf("%lf", mid);
            return 0;
        }
    }
    
    printf("%lf", l);
    
    return 0;
}






有效的完全平方数

bool isPerfectSquare(int num) {
    //处理1
    if(num == 1){
        return true;
    }

    int l = 0; int r = num / 2;
    double mid = 0;

    while(l <= r){
        mid = l + ((r - l) / 2);
        double x = mid * mid;
        if(x < num){
            l = mid + 1;
        }else if(x > num){
            r = mid - 1;
        }else{
            return true;
        }
    }

    return false;
    
}

你可能感兴趣的:(算法,C语言,算法,c语言)