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

704二分查找

这是第三次提交这个题目了 ,之前都是半途而废,坚持一两天就不刷了 ,导致每次刷的时候就看这个二分查找,整体来说没啥问题,注意力区间端点,

class Solution {
public:
    int search(vector& nums, int target) {

        int left = 0;
        int right = nums.size()-1;
        while(left<=right){

            //int middle = (left+right)/2;
            int middle = left+(right-left)/2;//防止溢出 等同于上面一行
            if (target==nums[middle]){
                return middle;
            }
            else if(target

要注意防止溢出;

27、移除元素

这个题也没啥大问题 用了暴力解法和双指针

class Solution {
public:
    int removeElement(vector& nums, int val) {
        //暴力枚举
        // int result = nums.size();
        // for(int i = 0;i

双指针自己写不出来,看了讲解才写了出来 注意fastindex是在寻找新数组所需要的元素,一旦找到,就把他赋值给新数组用下表slowindex表示。

35、搜索插入位置

这个题能用暴力解法自己写出来 当时就没思考用二分查找

二分查找的话最后返回值是right+1;因为循环截至时候left>right

class Solution {
public:
    int searchInsert(vector& nums, int target) {
        int n = nums.size();
        int left = 0;
        int right = n-1;
        while (left <= right) {
            int middle = left + (right-left)/2;
            if(target nums[middle]){
                left = middle +1;
            }else{
                return middle;
            }

        }
        return right+1;
        // int n = nums.size();
        // int left = 0;
        // int right = n - 1; // 定义target在左闭右闭的区间里,[left, right]
        // while (left <= right) { // 当left==right,区间[left, right]依然有效
        //     int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
        //     if (nums[middle] > target) {
        //         right = middle - 1; // target 在左区间,所以[left, middle - 1]
        //     } else if (nums[middle] < target) {
        //         left = middle + 1; // target 在右区间,所以[middle + 1, right]
        //     } else { // nums[middle] == target
        //         return middle;
        //     }
        // }
        // // 分别处理如下四种情况
        // // 目标值在数组所有元素之前  [0, -1]
        // // 目标值等于数组中某一个元素  return middle;
        // // 目标值插入数组中的位置 [left, right],return  right + 1
        // // 目标值在数组所有元素之后的情况 [left, right], 因为是右闭区间,所以 return right + 1
        // return right + 1;
    }
};

暴力解法如下:

class Solution {
public:
    int searchInsert(vector& nums, int target) {
        int left = 0;
        int right = nums.size();
        if(target < nums[left]){
            return 0;
        }
        // else if(target > nums[right-1]){
        //     return right;
        // }
        for(int i = 0;itarget){
                return i;
            }

        }
        return nums.size();
    }
};

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

这个题没有思路,属于中等难度,看了讲解之后才明白什么意思,原来还可以自己写函数,然后在主函数中调用,我一直以为只要写一个函数就可以了,需要再次看,

class Solution {
public:
    vector searchRange(vector& nums, int target) {
        int leftBorder = getLeftBorder(nums,target);
        int rightBorder = getRightBorder(nums,target);
        if((leftBorder==-2)||(rightBorder==-2)){
            return {-1,-1};
            }
        else if(rightBorder-leftBorder>1){
            return {leftBorder+1,rightBorder-1};
        }else{
            return {-1,-1};
        }
    }

private:
    int getRightBorder(vector& nums, int target){
        int left = 0;
        int right = nums.size()-1;
        int rightBorder = -2;
        while(left<=right){
            int middle = left+(right-left)/2;
            if(target& nums, int target){
        int left = 0;
        int right = nums.size()-1;
        int leftBorder = -2;
        while(left<=right){
            int middle = left+(right-left)/2;
            if(target<=nums[middle]){
                right=middle-1;
                leftBorder = right;
            }else{
                left = middle+1;
                
            }
        }
        return leftBorder;
    }
};

寻找target在数组里的左右边界,有如下三种情况:

  • 情况一:target 在数组范围的右边或者左边,例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}
  • 情况二:target 在数组范围中,且数组中不存在target,例如数组{3,6,7},target为5,此时应该返回{-1, -1}
  • 情况三:target 在数组范围中,且数组中存在target,例如数组{3,6,7},target为6,此时应该返回{1, 1}

这三种情况都考虑到,说明就想的很清楚了。

你可能感兴趣的:(代码随想录一刷,c++,算法)