代码随想录算法训练营第一天 | LeetCode704.二分查找、LeetCode27.移除元素、LeetCode977有序数组的平方

LeetCode 704.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

思路:根据二分查找的思路缩小寻找范围,从而找到目标值。时间复杂度为O(logn),空间复杂度为O(1)

难点:搞不清楚到底该是left<=right,还是left<right;同时在缩小范围的时候也需要思考到底是right=mid+1还是right=mid

当采取左闭右闭原则时,right = nums.size() -1, while循坏采用 left<=right判断,缩小范围时,left = mid + 1,right = mid - 1;

当采取左闭右开原则时,right = nums.size(), while循环采用left<right判断,缩小范围时,left = mid + 1,right = mid;(因为本身左闭右开并不包含右边,所以当目标值出现在数组左边时,缩小范围right=mid)

//采用左闭右闭原则
int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        while(left <= right){
            int mid = left + ((right - left) / 2);
            if(nums[mid] > target){
                right = mid - 1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
//采用左开右闭原则
int search(vector<int>& nums, int target) {
        int left = 0;
        int 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;
            }else{
                return mid;
            }
        }
        return -1;
    }

 LeetCode 27.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

思路:两种方法求解,首先是暴力求解,在两个循环里面进行,此时时间复杂度为O(n^2),空间复杂度为O(1) ,这也是最常用的,当遇到val时,将后面的所有值往前移动覆盖,再记录下移动的个数,总数相减即可得到最终结果;第二种方法是双指针法,采用快慢指针进行,快的指针和慢的指针从同一起点出发,快的指针在前面探路,当遇到不是val的值时就将其传给慢的指针,慢的指针再往前挪,这样往复进行,得到最终结果。此时时间复杂度为O(n),空间复杂度为O(1)

难点:时刻注意下标的增减,以免出错。

int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        for(int fast = 0; fast < nums.size(); fast ++){
            if(nums[fast] != val){
                nums[slow ++] = nums[fast];
            }
        }
        return slow;
    }

LeetCode 977.有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

请你设计时间复杂度为 O(n) 的算法解决本问题

思路:题目看着很简单,数组中的数平方后,再按非递减顺序排列即可,但是这样的话至少都需要O(n+nlogn)的时间复杂度(先一个循环将每个数平方,在使用快排进行排序),显然不符合题目要求。因此此路是行不通了。

这里还是需要借助一下刚刚讲过的双指针思想。

首先,数组本身是非递减顺序,因此最右边的数是最大的,但是平方后不一定是最大的,比如有这样一组数-100,....,2,10,显然-100的平方最大,而不是右边的数;但是我们能确定一件事,那就是,最大的数一定存在在两端,不可能存在在中间,由此就和归并排序类似了,新建一个数组,然后用两个指针分别指向原数组两端,比较所指向的元素哪个大,最大的填入新数组内,即可解决该问题。

难点:指针下标的移动以及左右两个指针的边界条件的判断

这里我还想说一点,题目限制了时间复杂度,但是没有明确限制空间复杂度,或许最优解就是牺牲一方换一方,牺牲了空间换时间,此时空间复杂度为O(n),与输入数据规模成正相关。

vector<int> sortedSquares(vector<int>& nums) {
      vector<int> result(nums.size() , 0);
      int k = nums.size() - 1;
      for(int i = 0, j = nums.size() - 1;i <= j;){
        if(nums[i] * nums[i] > nums[j] * nums[j]){
            result[k --] = nums[i] * nums[i];
            i ++;
        }else{
            result[k --] = nums[j] * nums[j];
            j --;
        }
      }
      return result;
    }

希望我的博客能够带给你一点帮助,我也还在学习中,如有问题,欢迎随时讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值