代码随想录算法训练营第一天| 704. 二分查找、35.搜索插入位置、34. 在排序数组中查找元素的第一个和最后一个位置、27. 移除元素

704. 二分查找

解题思路:
//左闭右闭
int search(int* nums, int numsSize, int target) {
    int length = numsSize;
    int left = 0;
    int right = length-1; //length比数组下标大1,故左闭右闭时right要length-1
    int ret = -1;
    int middle = 0;
    while (left <= right) {
        middle = (left + right)/2;
        if (nums[middle] < target) {
            left = middle + 1;
        } else if (nums[middle] > target) {
            right = middle - 1; //这里就要减一了,因为区间是[left,middle-1]
        } else {
            ret = middle;
            break;
        }
    }
    return ret;
}

//左闭右开
int search(int* nums, int numsSize, int target) {
    int length = numsSize; 
    int left = 0;
    int right = length;
    int middle = 0;
    int ret = -1;

    while (left < right) { //这里因为右开left不能等于right,否则区间不合法
        middle = (left+right)/2;
        if (nums[middle] > target){
            right = middle; //这里不减1,因为target在[left,middle)区间里
        }else if (nums[middle] < target) {
            left = middle + 1;
        }else {
            ret = middle;
            break;
        } 
    }
    return ret;
}

该题总结:我是真正一点算法题都没做过,从零开始的小白,感觉这个二分查找的两种方法都蛮简单的,二分法的关键在于区间定义,只要脑子里想着保证区间合法,有没有等于号,要不要减一,就一目了然了。


35.搜索插入位置

解题思路:
//左闭右开二分法
int searchInsert(int* nums, int numsSize, int target) {
    int left = 0;
    int right = numsSize;
    int mid = 0;
    while (left < right) {
        mid = left + (right - left)/2;
        if (nums[mid] < target) {
            left = mid + 1;
        }else if (nums[mid] > target) {
            right = mid;
        }else {
            return mid; //nums[mid] == target时该mid就是要插入的位置
        }
    }
    return right; //没有找到时直接插入到最右边
}

该题总结:题是简单题,就是在想新的元素要放在哪的时候,也就是return什么的时候有点晕,要想一会儿。

34. 在排序数组中查找元素的第一个和最后一个位置

解题思路:
//这题用左闭右闭要比左闭右开容易思考
int searchLeftborder(int *nums,int numsSize,int target) { //找左边界
    int left = 0;
    int right = numsSize - 1;
    int mid = 0;
    int leftborder = -1;
    while (left <= right) {
        mid = left + (right - left)/2;
        if (nums[mid] == target) {
            leftborder = mid;
            right = mid - 1;
        } else if (nums[mid] >target) {
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return leftborder;
}
//左右边界找法思路上是对称的
int searchRightborder(int *nums,int numsSize,int target) { //找右边界
    int left = 0;
    int right = numsSize - 1;
    int mid = 0;
    int rightborder = -1;
    while (left <= right) {
        mid = left + (right - left)/2;
        if (nums[mid] == target) {
            rightborder = mid;
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid -1;
        } else {
            left = mid + 1;
        }
    }
    return rightborder;
}

int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    int leftborder = searchLeftborder(nums,numsSize,target);
    int rightborder = searchRightborder(nums,numsSize,target);
    *returnSize = 2; //这里必须要定义返回数组的大小,虽然后面用不到
    int *resNums = (int*)malloc(sizeof(int) * 2);
    resNums[0] = leftborder;
    resNums[1] = rightborder;
    return resNums;
}

该题总结:这个中等题,一开始给哥们搞得焦头烂额的,他的左边界和右边界的算法,对于我这种小白来说真是费脑子,不过最后终于还是弄明白了,花了得有两个小时就这一道题。

27. 移除元素

解题思路:
//双指针法是这题的精髓
int removeElement(int* nums, int numsSize, int val) {
    int slow = 0;//慢指针
    for (int fast = 0; fast < numsSize; fast++) { //快指针
        if (nums[fast] != val) { //快指针所指元素非val时,将快指针所指的值赋给慢指针所指的值
            nums[slow] = nums[fast];
            slow++;
        }
    }
    return slow;
}

该题总结:在刚才那道题烧了半天脑之后迎来一道思路很舒服的题,不管是暴力解法还是双指针法都很简单,主要还是要学习一下双指针法这种思路,真的很nice。
总耗时约5小时左右,主要是第一次写题,也是第一次写博客,花了好长时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值