【代码随想录】数组——“双指针”相关题目

这篇博客介绍了C++中数组和字符串的常见操作,包括移除元素、删除有序数组中的重复项、移动零以及比较含退格的字符串。使用了快慢指针技巧,以及栈和双指针的方法来解决问题。此外,还展示了如何处理数组的内存限制,以及在处理字符串时模拟退格操作的策略。
摘要由CSDN通过智能技术生成

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

27. 移除元素

通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n=nums.size();
        int slow=0;
        for(int fast=0;fast<n;fast++){
            if(nums[fast]!=val){//快慢指针判断条件,自己实现起来有点晕
                nums[slow]=nums[fast];
                slow++;
            }
        }
        return slow;
    }
};

 

26. 删除有序数组中的重复项

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n=nums.size();
        int slow=0;
        for(int fast=1;fast<n;fast++){
            if(nums[slow]!=nums[fast]){//当nums[slow]==nums[fast]时,应保留slow的位置,让后面的覆盖它。当两者不等时,才有后面的操作
                slow++;//不同之处就先让slow++
                nums[slow]=nums[fast];
            }
        }
        return slow+1;

    }
};

283. 移动零

1、让slow,fast都有等于0

2、如果nums[fast]不等于0,就让nums[fast]覆盖nums[slow],并让slow++

3、将slow及之后的元素赋0

为了定义少一个指针fast,直接for(int num:nums)来遍历

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int slow=0;
        int n=nums.size();
        for(int num:nums){
            if(num!=0){
                nums[slow]=num;
                slow++;
            }
        }
        while(slow<n){
            nums[slow]=0;
            slow++;
        }
        
    }
};

844. 比较含退格的字符串

第一种方法:栈法(字符串当栈来用)。匹配的问题(比如括号问题)都可以考虑栈。

本题确实可以使用栈的思路,但是没有必要使用栈,因为最后比较的时候还要比较栈里的元素,有点麻烦

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        string ss;//不用直接用栈,将字符串当栈来用
        string tt;
        for(int i=0;i<s.size();i++){
            if(s[i]!='#') ss+=s[i];//直接串在后面
            else if(!ss.empty()) ss.pop_back();//串还有这操作??
            
        }
        for(int j=0;j<t.size();j++){
            if(t[j]!='#') tt+=t[j];//直接串在后面
            else if(!tt.empty()) tt.pop_back();//串还有这操作??
        }
        if(ss==tt) return true;//直接判断两个字符串是否相等
        else return false;
    }
};

第二种方法:双指针法

两个字符串都从后往前遍历,记录#的个数,并模拟消除字符

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        int sSkipnum=0,tSkipnum=0;//记录字符串中#的数量
        int i=s.size()-1;
        int j=t.size()-1;
        while(1){
            while(i>=0){
                if(s[i]=='#') sSkipnum++;
                else{
                    if(sSkipnum>0) sSkipnum--;//sSkipnum--之后能直接跳到i--,表明已经跃过了#前面的那个符号(模拟消除)
                    else break;
                }
                i--;//能到i--前提是不提前break掉
            }
            while(j>=0){
                if(t[j]=='#') tSkipnum++;
                else{
                    if(tSkipnum>0) tSkipnum--;
                    else break;
                }
                j--;//能到j--前提是不提前break掉
            }
            if(i<0 || j<0) break;
            if(s[i]!=t[j]) return false;//如果字符不相等,直接返回false
            i--;
            j--;
        }
        if(i<0 && j<0) return true;
        return false;
    }
};

977. 有序数组的平方

(自己实现时细节差了点东西,见注释)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> res(nums.size(),0);//先把res的大小定义出来,否则后面K--会导致指针的非0偏移量访问
        int left=0;
        int right=nums.size()-1;
        int k=nums.size()-1;
        while(left<=right){
            if(nums[left]*nums[left]<nums[right]*nums[right]){
                res[k]=nums[right]*nums[right];//一开始自己的想法是res.push_back(),在循环结束之后才reverse一下的
                k--;
                right--;
            }
            else{
                res[k]=nums[left]*nums[left];//直接一开始将k定义到res数组大小,后面不断--,就解决了上面那个问题
                k--;
                left++;
            }  
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值