刷算法记录-数组篇-折半查找和删除元素

50 阅读3分钟

1. 二分查找/折半查找

输入:nums
动作: 数组中寻找元素target cpp实现
方法: 折半查找
输出: 值的序号(0开始)
leetcode:leetcode.cn/problems/bi…

class Solution {
public:
   int search(vector<int>& nums, int target) {
       int left = 0;
       int right = nums.size() - 1;
       while (left <= right) {
           // int mid = (left + right) / 2;
           // 防止溢出
           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;
   }
};

2. 删除元素

输入: 一个一维数组 nums
动作: 删除数组中元素为val的全部元素
思路: 双指针法,一个快指针指向一维数组nums,一个慢指针指向剩余元素个数
输出: 剩余元素个数slow
leetcode: leetcode.cn/problems/re…

class Solution {
public:
   int removeElement(vector<int>& nums, int val) {
       // 删除val=2的元素 [0,1,2,3,2]=>[0,1,3,_,_] 快慢指针法
       int slow=0;
       //i 指的是fast指针
       // fast指针指向原数组
       //slow指针指的是新数组的元素个数
       for(int i=0;i<nums.size();i++){
           if(val!=nums[i]){
               nums[slow]=nums[i];
               slow++;
               //nums[show++]=nums[i]
           }
       }
       return slow;
   }
};

3.有序数组的平方

输入: 一个有序一维数组 nums
动作: 平方后不递减输出
思路:
1.暴力 O(nlogn+n^2) nlogn是平方后排序
2.双指针法,一个左指针,一个右指针 每次把最小的放在最终位置
输出: 新数组res
leetcode: leetcode.cn/problems/sq…

我写的: 结果错误 不理解为什么不能从左到右,要把index从右到左

class Solution {
public:
   vector<int> sortedSquares(vector<int>& nums) {
       //结果数组初始化
      vector<int> res(nums.size(),0);
      int index=0;
      // 定义两个指针 在头部和尾部 ,指向当前最小的 从前往后
      // 非递减顺序 排序
       for(int left=0,right=nums.size()-1;left<=right;){
           if(nums[left]*nums[left]>nums[right]*nums[right]){
               // 等于小的
               res[index++]=nums[right]*nums[right];
               right--;
           }
           else{
               res[index++]=nums[left]*nums[left];
               left++;
           }
       }
       return res;
   }
};

正确答案:

image.png

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        //结果数组初始化
       vector<int> res(nums.size(),0);
       int index=nums.size()-1;
       // 定义两个指针 在头部和尾部 ,指向当前最小的 从前往后
       // 非递减顺序 排序
        for(int left=0,right=nums.size()-1;left<=right;){
            if(nums[left]*nums[left]<nums[right]*nums[right]){
                // 等于小的
                res[index--]=nums[right]*nums[right];
                right--;
            }
            else{
                res[index--]=nums[left]*nums[left];
                left++;
            }
        }
        return res;
    }
};

4. 长度最小的子数组

  1. 暴力破解法-O(n^2) 双层for循环-超出时间限制
class Solution {
public:
  int minSubArrayLen(int target, vector<int>& nums) {
      // 宏定义:int最大值INT32_MAX 
      int result=INT32_MAX;
      int subLength=0;
      // 第一个指针i
      // int i=0;
      // 第二个指针j
      for(int j=0;j<nums.size();j++){
          int sum=0;
          // 这里用while
          for(int i=j;i<nums.size();i++){
              sum+=nums[i];
              if(sum>=target){
                  subLength=(i-j+1);
                  // 找长度最小
                  result=result<subLength?result:subLength;
                  break;
              }
          }
      }
      return result==INT32_MAX?0:result;
  }
};

2. 双指针滑动窗口法-O(n)----for+while

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        // 宏定义:int最大值INT32_MAX 
        int result=INT32_MAX;
        int sum=0;
        int subLength=0;
        // 第一个指针i
        int i=0;
        // 第二个指针j
        for(int j=0;j<nums.size();j++){
            sum+=nums[j];
            // 这里用while
            while(sum>=target){
                subLength=(j-i+1);
                // 找长度最小
                result=result<subLength?result:subLength;
                //===============重要: 滑动窗口滑动1个==========
                sum-=nums[i];i++;
            }
        }
        return result==INT32_MAX?0:result;
    }
};