模型总结:前后指针法

零、前言

作者为了找工作和实习开启了自己的算法之旅,并将刷到的各种题型总结成模型分享给大家。

一、最基本的前后指针法

本文将持续更新。

27. 移除元素

1.使用场景

前后指针法,与其说是一个题型,不如说是一种思想:

在一个数组中筛选符合条件的元素,并放在原数组中。

2.思路

  • 定义一个快指针和一个慢指针。
  • 快指针依次遍历数组,在for循环内递增。
  • 慢指针在快指针筛选出来符合条件的元素时,nums[slow]=nums[fast],slow++
  • 总结来说就是slow筛选下标,而fast来筛选元素。

3.实现

class Solution {
public:
    int removeElement(vector& nums, int val) {
        int slowstr=0;//定义慢指针为数组下标
        int faststr=0;//定义快指针指向所需的值
        for(faststr=0;faststr<nums.size();faststr++)
        {
            if(nums[faststr]!=val)
            {
                nums[slowstr]=nums[faststr];
                slowstr++;
            }
        }
        return slowstr;
    }
};

在移除元素中就体现为移除满足条件的元素。然后再放在原数组中。

二、变式一:多元素去重

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

1.思路

多元素去重,本质上就是筛选出数组中多个相等的元素。题目要求使用原数组,因此可以考虑前后指针法,只需要将slow++放在nums[slow]=nums[fast]之后即可。

2.实现

class Solution {
public:
    void moveZeroes(vector& nums) {
        int faststr=0;
        int slowstr=0;
        for(faststr=0;faststr<nums.size();faststr++)
        {
            if(nums[faststr]!=0)
            {
                nums[slowstr]=nums[faststr];
                slowstr++;
            }
        }
        for(int i=slowstr;i<faststr;i++)
        {
            nums[i]=0;
        }
    }
};

本题给我们的启示为,当在相同数组中进行筛选的时候可以优先考虑前后指针法,这里给了条件是升序数组。所以说还需要有一定的条件,根据该条件来调整代码即可。

三、变式二:筛选元素具有某种属性

844. 比较含退格的字符串

1.思路

首先依然满足条件,筛选出来的元素存放在原数组中,而具有某种属性最终会体现在slow指针如何处理上。fast指针继续正常遍历即可。

在这里每当发生退格的时候,slow--,并且当--为小于0的数时,将其置为0。

2.实现

class Solution {
public:
    string StrSolution(string str)
    {
        int faststr=0;
        int slowstr=0;
        for(faststr=0;faststr<str.size();faststr++)
        {
            if(slowstr<0)
            {
                slowstr=0;
            }
            if(str[faststr]!='#')
            {
                str[slowstr]=str[faststr];
                slowstr++;
            }
            else
            {
                slowstr--;
            }
        }
        if(slowstr<0)
        {
            slowstr=0;
        }
        str[slowstr]='\0';
        str = str.substr(0, slowstr);
        return str;
    }
    bool backspaceCompare(string s, string t) {
        string s1=StrSolution(s);
        string s2=StrSolution(t);

        if(s1==s2)
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
};

3.发现的问题

其中如果不使用字符串切割,string类不会因为看到'\0'而结束。但是如果在构造的时候有'\0'那么可以结束。因此还需要进行字符串切割。

四、总结

前后指针法不是一个固定的题型,重要点在于识别。

  • 当发现存放的元素放在原数组中的时候,就可以考虑使用前后指针法了。往往还伴随着一些条件。
  • 筛选的元素可以带有一些属性,使用slow指针来体现。

本文将持续进行更新。

全部评论
这个厉害啊
点赞 回复 分享
发布于 2022-10-19 12:34 山西

相关推荐

写不来代码的小黑:这么小的城市能有做it的公司也不容易
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务