代码随想录算法训练营第一天|力扣704. 二分查找、力扣27. 移除元素

发布时间 2023-07-27 21:49:34作者: zccccc!

数组

1.数组理论基础

数组是存放在连续存储空间中的相同类型数据的集合

 

二分法(力扣704.)

对于默认升序的数组,进行二分法搜索下标

  • 易错点

    1. while(left<right)还是(left<=right)

    2. 更新区间的时候,right=middle还是middle-1

  • 左闭右闭写法

    1. right = maxsize-1

    2. while(left<=right)middle=(left+right)/2

    3. if(nums[middle]>target)

    4. right=middle-1

    5. else if (nums[middle]<target)

    6. left = middle +1;

    7. return -1;

      class Solution {
         public int search(int[] nums, int target) {
             //左闭右闭
             int left = 0;
             int right = nums.length - 1;
             if(target<nums[0]||target>nums[nums.length-1]){
                 return -1;
            }
             while(left<=right){
             int middle = (left+right)/2;
             if(nums[middle]<target){
                 left = middle + 1;
                 middle = (left+right)/2;
            }else if(nums[middle]>target){
                 right = middle - 1;
                 middle = (left+right)/2;
            }else{
                 return middle;
            }
            }
             return -1;
        }
      }

       

  • 左闭右开写法

    1. right = maxsize

    2. while(left<right)middle=(left+right)/2

    3. if(nums[middle]>target)

    4. right=middle

    5. else if nums[middle]<target

    6. left=middle+1

    7. else return middle

    8. return -1;

      class Solution {
         public int search(int[] nums, int target) {
             //左闭右开
             int left = 0;
             int right = nums.length;
             if(target<nums[0]||target>nums[nums.length-1]){
                 return -1;
            }
             while(left<right){
             int middle = (left+right)/2;
             if(nums[middle]<target){
                 left = middle + 1;
            }else if(nums[middle]>target){
                 right = middle;
            }else{
                 return middle;
            }
            }
             return -1;
        }
      }

       

移除元素(力扣27.)

  • 原始思路:由于题目中说元素的顺序可以改变;遍历数组,遇到想要删除的元素直接将数组最后一个元素赋值到此位置,并令数组长度自减;与此同时,最后一个元素也有可能是要删除的值,因此令循环的i自减,重新对此元素进行检查。

    class Solution {
       public int removeElement(int[] nums, int val) {
           int len = nums.length;
           for(int i=0;i<len;i++){
               if(nums[i]==val){
                   nums[i]=nums[len-1];
                   len--;
                   i--;
              }
          }
           return len;
      }
    }
  • 其实完成就是库函数erase :O(n)复杂度

  • 双指针思路:此时顺序可以不变;定义快慢指针;快指针用来寻找正确的值,用来赋给慢指针指向位置;

    1. slow=0

    2. for(fast =0;fast<nums.size;fast++)

    3. if(nums[fast]!=val)

    4. nums[slow]=nums[fast]

    5. slow++

    6. return slow

class Solution {
   public int removeElement(int[] nums, int val) {
       //快慢指针,快指针剔除错误元素赋给慢指针指向的位置
       int low = 0;
       for(int fast = 0; fast < nums.length; fast++){
           if(nums[fast] != val){
               nums[low] = nums[fast];
               low++;
          }
      }
       return low;
  }
}