条件:数组内无重复数据,升序排列,所以可以考虑二分(有重复则一个数会对应多个下标)
Tips:二分查找,不是mid指向的数据不断和target比较,而是不断缩小区间。所以需要规范区间边界和边界更新,注意:

  1. 边界需要是有符号的,如int,保证是正整数;
  2. 想要保证不溢出,可以利用边界自身当作判断条件,如while(left <= right)(注意这里是<=还是<);
  3. 更新时保证left和right变为mid后一个或者前一个,如果更新为mid会导致溢出超时;
    此处为允许left = right(左闭右闭)的情况:
点击查看代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        size_t n = nums.size();
        size_t left = 0;
        size_t right = n - 1;

        while(left <= right){

            size_t mid = left + (right - left)/2;

            if(nums[mid] > target) right = mid - 1;
            else if(nums[mid] < target) left = mid + 1;
            else if(nums[mid] == target) return mid;
        }
        return -1;
    }
};

另一种方法是左闭右开,对应right可以为size而非size-1,而此时while就不是<=而是<了,容易疏忽的是,left闭合就意味着要left+1跳过已检查的mid,见代码:

点击查看代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size();
        

        while( left < right ){
            
            int mid = left + (right - left) / 2;

            if(nums[mid] > target) right = mid;
            else if(nums[mid] < target) left = mid + 1; // 因为左闭,所以要+1跳过已检查的mid
            else if(nums[mid] == target) return mid;

        }return -1;
    }
 };

条件:留下数组中和val不同的,同时统计个数,且不要求顺序
Tips:这里不需要使用排序算法那样的交换,因为当出现多个连续val时会出现漏覆盖的情况,直接找到第一个非val的值后替换到第一位,以此类推即可:

点击查看代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {

        int k = 0; //记录不等于元素数量

        for(int temp = 0; temp < nums.size(); temp++){

            if(nums[temp] != val) {
                nums[k] = nums[temp];
                k++;
            }
        }
        return k;
    }
};