[C++学习] 数组 移除元素 代码随想录 LeetCode题 代码 笔记

数组在内存中的储存地址是连续的,不能单独删除某个元素,只能覆盖。

常用方法——双指针法:在一个 for 循环中完成两个 for 循环的工作

1、同向扫描(快慢指针法):指针1 和 指针2 都从头到尾,方向相同,但速度不同,以不同策略移动

2、反向扫描:指针1从头到尾,指针2从尾到头,在中间汇合

一、 LeetCode题 27.移除元素 27. 移除元素 - 力扣(LeetCode)

题目描述:

1、暴力解法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0;
        for(int i = 0; i < nums.size(); i++){
            if(nums[i]!=val){
                nums[k] = nums[i];
                k++;
            }
        }
        return k;
    }
};

2、快慢指针法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++){
            if (nums[fastIndex] != val){
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;

    }
};

3、反向扫描法(优化,避免了需要保留元素的重复赋值):当左边的元素等于目标值时,用右边的元素覆盖

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int leftIndex = 0;
        int rightIndex = nums.size() - 1;
        while (leftIndex <= rightIndex){
            if (nums[leftIndex] == val){
                nums[leftIndex] = nums [rightIndex];
                rightIndex--;
            }
            else leftIndex++;
        }
        return leftIndex;

    }
};

二、 LeetCode题 283.移动零 283. 移动零 - 力扣(LeetCode)

题目描述:

代码:与上一道题思路类似。

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int slowIndex = 0;
        int rightIndex = nums.size() - 1;
        int k = 0;
        for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++){
            if(nums[fastIndex] != 0){
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
            else k++;
        }

        while(k > 0){
            nums[nums.size()  - k--] = 0;
        }
    }
};

三、 LeetCode题 844.比较含退格的字符串 844. 比较含退格的字符串 - 力扣(LeetCode)

题目描述:

代码:双指针法,当快指针指向元素为退格字符‘#’,慢指针减一,deleteString 函数返回处理完退格信息的字符串。

class Solution {
public:
    string deleteString(string& s, int n) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < n; fastIndex++) {
            if (s[fastIndex] != '#') {
                s[slowIndex] = s[fastIndex];
                slowIndex++;
            } else {
                if (slowIndex > 0){
                    slowIndex--;
                }
            }
        }

        string result;
        for(int i = 0; i < slowIndex; i++){
            result = result + s[i];
        }
        return result;
    }
    bool backspaceCompare(string s, string t) {
        return deleteString(s, s.length()) == deleteString(t, t.length());
    }
};

力扣官方题解:

定义两个指针,分别指向两字符串的末尾。每次让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S[i] == '#') {
                    skipS++, i--;
                } else if (skipS > 0) {
                    skipS--, i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T[j] == '#') {
                    skipT++, j--;
                } else if (skipT > 0) {
                    skipT--, j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S[i] != T[j]) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--, j--;
        }
        return true;
    }
};

三、 LeetCode题 977.有序数组的平方 977. 有序数组的平方 - 力扣(LeetCode)

题目描述:原数组是有序的,则数组平方的最大值只可能出现在原数组的两端,定义一个新数组逆序保存原数组对应元素平方后的最大值,两个指针分别从前往后和从后往前。

代码:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int leftIndex = 0;
        int rightIndex = nums.size() - 1;
        int k = rightIndex;
        vector<int> result(nums.size());
        while (leftIndex <= rightIndex) {
            if (nums[leftIndex] * nums[leftIndex] < nums[rightIndex] * nums[rightIndex]) {
                result[k--] = nums[rightIndex] * nums[rightIndex];
                rightIndex--;
            }
            else {
                result[k--] = nums[leftIndex] * nums[leftIndex];
                leftIndex++;
            }
        }
        return result;
    }
};

注意:vector 定义时需要申请空间,没有申请空间时不能直接赋值

 本文根据代码随想录顺序刷题。代码随想录 (programmercarl.com)

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值