(第1天)【leetcode题解】704、二分查找 27、移除元素

704、二分查找

题目描述:在一个升序数组中找到目标值target,返回下标;目标值不存在则返回-1.

  1. 暴力解法:遍历数组,搜索目标值target
    int search(vector<int>& nums,int target){
        for (int i=0;i<nums.size();i++){
            if(nums[i]==target){
                return i;}
    }
    return -1;
    }

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

  2. 二分查找 

对区间的定义决定了不同的写法。

这里用双闭区间。[0,nums.size()-1]搜索区间包括0和数组的长度减一的索引

循环条件:左指针可以在不断右移之后达到初始right指向的位置(nums.size()-1),因此循环条件为(left<=right)。

mid计算:为了防止两个值计算结果导致大数越界,mid = (right-left)/2+left

nums[mid]<target:表明目标值(如果存在的话)应该在[mid+1,right]的范围内

nums[mid]>target:表明目标值应该在[mid+1,right]的范围内 

    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;//左指针、右指针
        while (left <= right){
            int mid = (right-left)/2+left;//找出中间索引
            if (nums[mid] < target){
                left = mid + 1;
            }else if (nums[mid] > target){
                right = mid -1;
            }else{
                return mid;
            }
        }
        return -1;
    }

时间复杂度:O(logn);空间复杂度:O(1)

27、移除元素

题目描述:移除一个数组nums中值为val的元素,返回移除元素之后数组的长度

注意:数组在内存中是连续的,因此这里对元素的移除本质上是对原数组的覆盖

1.暴力解法

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;j<size-1;j++){
                nums[j] = nums[j+1];
                }
            size--;//数组长度减一
            i--;//所有数值往前移一位,i也要向前移一位,继续从前移序列的第一位开始继续判断
        }
    }
    return size;
}

时间复杂度:O(n**2);空间复杂度:O(1)

对于i--解释的一个例子:

当i=0时,进入if语句,把所有之后的元素前移,这时完成了一次“移除”。

若没有i--,那么下一次循环时i=1,前移之后的第一个新元素(i=0的元素)就不会被遍历到。

2.双指针法(快慢指针法)

初始化两个指针。

快指针:用来在原数组中搜索符合条件的元素,慢指针:用来覆盖原数组,从0开始给新数组赋值。

最终,慢指针的值就是移除所有val之后的数组长度

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

int removeElement(vector<int>& nums,int val){
    int slowindex = 0;//慢指针,用来从0给原指针赋值,覆盖原指针
    for (int fastindex = 0;fastindex<nums.size();fastindex++){
        //fastindex从0在数组中搜索符合要求的值
        //搜索到符合要求的值之后,就把值按顺序赋值到数组中,覆盖原数组
        if (nums[fastindex]!=val){
            nums[slowindex] = nums[fastindex];
            slowindex++;
        }
    } 
    return slowindex;//移除所有val之后数组的长度
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值