代码随想录day1||| 704. 二分查找、27. 移除元素

704、二分查找
27、移除元素

704 二分查找

解题思路

折半查找思路:

首先要确定边界 这里写的是左闭右闭(左右边界都能取到)
定义左右指针left、right记录查找范围,中间指针mid比较target值

  1. target < nums[mid],查找值小于中间值,右指针等于中间值-1,right = mid - 1;
  2. target > nums[mid],查找值大于中间值,左指针等于中间值+1,left = mid + 1;
  3. target == nums[mid],查找值就是中间值,返回中间值下标;
  4. 否则返回-1。

注意:

  • 如果左闭右开的话[left,right) 循环的边界的是while(l<r);因为让left==right没有意义;例如[1,1)。
  • 此时右边界的值取不到,修改时应注意r=mid;
// 时间复杂度:O(n^2) 空间复杂度:O(1)
class Solution {
public:
    int search(vector<int>& nums, int target) {
     int left = 0; 
     int right = nums.size()-1; //左右都闭
     while(left <= right){
        int mud = (right - left)/2 + left; // 防止溢出 等同于(left + right)/2 
        if(nums[mud] == target){
            return mud;
  } 
  else if (nums[mud] > target){
           right = mud-1; // right的值不包括中间人
   }
      else {
    left = mud+1;
}
     }
return -1;
    }
};
收获

其实主要就是对区间的定义没有理解清楚,在循环中没有始终坚持根据查找区间的定义来做边界处理。
区间的定义就是不变量,那么在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。

27、移除元素

解题思路

暴力法
// 暴力法
// 时间复杂度:O(n^2) 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
     int size = nums.size();        
for(int i = 0;i < size;i++){
   if( nums[i] == val){  // 发现需要移除的元素,就将数组集体向前移动一位
      for(int j = i+1; j < size; j++){
          nums[j-1] = nums[j];
      }
      size--;
      i--; // 因为下表i以后的数值都向前移动了一位,所以i也向前移动一位
   }
}
return size;
    }
};
双指针

定义两个指针,一个快指针一个慢指针。快指针遍历旧数组,慢指针只在没有查询到所需元素时++,然后进行赋值操作

//  时间复杂度:O(n)O(n)  空间复杂度:O(1)O(1)

class Solution {
    public int removeElement(int[] nums, int val) {
        int fast = 0;
        int slow = 0;
        for(;fast<nums.length;fast++){
            if(nums[fast]!=val){
                nums[slow++] = nums[fast];
                
            }
        }
        return slow;
    }
}
收获

快慢双指针,两个指针从同一位置出发(数组头部)。检查快指针的值是否是需要删除的数值,如果不是:快指针指向的值赋值给慢指针,快指针++,慢指针++。如果是:快指针++。直到快指针到数组结尾。此时返回慢指针的值就是删除操作后的数组长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值