代码随想录练习Day1|704.二分查找|27.移除元素

704.二分查找

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


思路讲解:

        典型的二分法,二分思路比较简单,注意使用前提:有序数组、无重复元素(有重复也可以使用,但要确定下标)

        具体查看代码随想录原文:二分查找思路讲解


代码 

左闭右闭(target在[left,right]区间里)

class Solution {
public:
    int search(vector& 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;
            if(nums[mid]

        需要注意三点:

        1.不能简单写成 mid=(left+right)/2,当left和right都很大时,可能会溢出。

        2. while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

        3. if (nums[mid] > target) right 要赋值为 mid - 1,因为当前这个nums[mid]一定不是target,那么接下来要查找的左区间结束下标位置就是 mid - 1

        复杂度:T = O(logn) M = O(1)


左闭右开(target在[left,right)里)

class Solution {
public:
    int search(vector& nums, int target) {
        int left=0;
        int right=nums.size();
        while(lefttarget)
                right=mid;
            if(nums[mid]

        

        1.while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的

        2.if (nums[mid] > target) right 更新为 mid,因为当前nums[mid]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为mid,即:下一个查询区间不会去比较nums[mid]。

       复杂度:T = O(logn) M = O(1)

27.移除元素

  •         给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
  •         不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组
  •         元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路讲解

       这道题目重点在于理解数组的覆盖原则:如果数值等于val,那我们就可以直接将其进行覆盖,从而可以达成目标。具体覆盖有两种方法:暴力法--当判断该值是val时,将val后面的值前移一位进行覆盖。和双指针法:使用两个指针,第一个指针不断对数组进行遍历,寻找不为val的元素第二个指针对满足目标的元素进行存储,并对数组下标进行更新。

        具体查看代码随想录原文:移除元素思路讲解 


代码   

        暴力法

class Solution {
public:
    int removeElement(vector& nums, int val) {
    int i=0;
    int j=0;
    int size=nums.size();
    for(i;i

        复杂度:T = O(n^2) M = O(1)

        双指针法   

class Solution {
public:
    int removeElement(vector& nums, int val) {
        int findex=0;  //快指针
        int sindex=0;  //慢指针
        for(findex=0;findex

        注意:典型的双指针法:通过一个双指针在一个for循环中完成了两个for循环的任务。 从而降低了时间复杂度。

        快指针:目标数组的下一个需要判断的值

        慢指针:目标数组的下一个需要添加的长度

复杂度:T = O(n) M = O(1)

附加题

        35.搜索插入位置

class Solution {
public:
    int searchInsert(vector& nums, int target) {
        int left=0;
        int right=nums.size()-1;
        int mid=0;
        while(left<=right){
            mid=left+(right-left)/2;
            if(nums[mid]>target)
                right=mid-1;
            if(nums[mid]

  复杂度:T = O(nlogn) M = O(1)

        34. 在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector searchRange(vector& 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;
            if(nums[mid]0&&nums[leftindex]==nums[leftindex-1])
                        leftindex--;  //找左边界
                    while(rightindex

复杂度:T = O(nlogn) M = O(1)

你可能感兴趣的:(算法题练习,算法,leetcode,数据结构)