02. 移除元素

移除元素

LeetCode链接

https://leetcode.cn/problems/remove-element/description/?envType=study-plan-v2&envId=top-interview-150

解题思路

1.利用函数api(暴力)

解题思路

  1. 利用迭代器遍历数组
  2. 等于val,就调用 erase 函数删除元素;反之,迭代器后移
  3. 最后利用 size 函数返回元素个数

代码流程

class Solution {
  public:
      int removeElement(vector<int>& nums, int val) {
          //遍历
          for(vector<int>::iterator it = nums.begin(); it != nums.end();){
              if(*it == val){
                  nums.erase(it);  //删除
              }else{
                  it++;  //指针后移
              }
          }
          return nums.size();
      }
  };

复杂度分析
时间复杂度:O(log(n))
空间复杂度:O(1)

2.双指针

解题思路

  1. 利用不需要考虑返回值后数据的特性
  2. 使用两个指针,一个用于遍历数组(right),一个指向保存数据的索引(left)
  3. 当值不相等时,数据需要保留,将right指向的值赋值给left,left 和 right 指针后移;反之,right 指针后移
  4. 最终 left 的值为元素个数

代码流程

class Solution {
  public:
      int removeElement(vector<int>& nums, int val) {
      int left = 0;

      for(int right = 0; right < nums.size(); right++){ //遍历
          if( val != nums[right]){    //元素需要保留
              nums[left] = nums[right];
              left++;
          }
      }

      return left;
      }
  };

复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)

3.双指针(优化)

解题思路

  1. 上一个方案最差情况我们需要遍历2次,我们可以将指针定义在数组头部和末尾,同时向中间移动,可以将遍历次数降低到1次
  2. 当left == val,将 right 指向的值复制到 left,并将 right 左移;反之 left 右移。知道 right < left 退出
  3. 此时 left 即为元素个数

代码流程

//双指针优化
class Solution {
public:
  int removeElement(vector<int>& nums, int val) {
     int left = 0;
     int right = nums.size()-1;

      //遍历
     while(right >= left){
         if(nums[left] == val){
             nums[left] = nums[right]; //执行条件
             right--;
         }else{
             left++;
         }
     }

     return left;
  }
};

复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)

总结

此类题型有一个通用模板:

  1. 遍历
  2. 通过不同条件执行不同的操作,指针进行相应的移动
posted @ 2023-08-31 22:18  异世界穿越中!.!  阅读(27)  评论(0)    收藏  举报