训练营day1| 704. 二分查找、27. 移除元素

704.二分查找

  • 题目链接704.二分查找
  • 独立思路:二分查找只针对有序的顺序表,从中间值开始查找,逐渐缩小范围。
  • 问题(已解决):但第一次提交时while循环的条件写成low < high,忽略了low=high时也是满足条件的。(写的是左右闭区间的情况)
  • 时间复杂度:O(log2n)
  • 空间复杂度:O(1)
class Solution {
public:
int search(vector<int>& nums, int target) {
    int n = nums.size();
    int low = 0;
    int high = n-1;
    while(low <= high){     //第一次提交的是<,只有一个元素时运行结果时错的
        int mid = (low + high)/2;	//写成mid=low+(high-low)/2更好,防止溢出
        if(target > nums[mid])
            low = mid+1;
        else if(target < nums[mid])
            high = mid-1;
        else 
            return mid;
    }
    return -1;
}
};

27.移除元素

  • 题目链接27.移除元素
  • 独立思路:用k来记录数组中非val值的元素,遍历数组,非val值的元素将数组前面的k个位置覆盖即可
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0;  //用来记录数组中非val的元素个数
        for(int i = 0; i < nums.size(); i++){
            if(nums[i] != val){
                nums[k] = nums[i];
                k++;
            }
        }
        return k;
    }
};

  • 另解1(暴力算法) :遍历数组,遇到值为val的元素,需要把其后续的所有元素都往前移动一位。
  • 问题(已解决):第一次提交时,第二个for循环后面没有进行下标i以及元素大小n的处理,导致运算的结果是错误的。
  • 时间复杂度:O(n2)
  • 空间复杂度:O(1)
class Solution{
public:
    int removeElement(vector<int>& nums, int val){
        int n = nums.size();
        int k = 0;
        for(int i = 0; i < n; i++){
            if(nums[i] == val){
                for(int j = i+1; j < n; j++){   //把后面的都往前移
                    nums[j-1] = nums[j];
                }
                i--;	//所有元素往前移1位,i应该保持不变。因为for中i++,所以要--才保持不变
                n--;	//待排序的size会减少1位
            }
            else
                k++;
        }
        return k;
    }
};

  • 另解2(双指针):slow指针指向新数组的下标,fast用来遍历旧数组
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
class Solution{
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        int fast = 0;
        int n = nums.size();
        for( ; fast < n; fast++){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值