尺取法(一)

尺取法(一)

尺取法又叫做双指针法。主要分为同向双指针和反向双指针。算法相对二分来说比较简单,是一个单一的算法。没有二分那么容易跟其他的题目进行嵌套。下面主要写一点题目吧。

1.删除排序数组中的重复项

链接: 删除排序数组中的重复项.

解题思路

这是一个比较简单的题,一个典型的同向双指针。i为快指针,j为慢指针。i和j都从头到尾扫描数组a[]。i指针走得快,逐个遍历整个数组;j指针走得慢,它始终指向当前不重复部分的最后一个数。也就是说,j用于获得不重复的数。快指针i++,如果此时a[i]不等于慢指针j指向的a[j],就把j++,并且把a[i]复制到慢指针j的当前位置a[j]。i扫描结束后,a[0]到a[j]就是不重复数组。

题解
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size()==0)
        return 0;
        int i;
        int j=0;
        for(i=1;i<nums.size();i++){
            if(nums[j]!=nums[i]){
                j++;
            }
            nums[j]=nums[i];
        }
        return j+1;
    }
};
2.水果成篮

链接: 水果成篮.

解题思路

看懂题目的意思后,其实很好理解。就是在数组中找一个最长的子序列,然后里面只有重复的两个元素。返回这个子序列的长度,很显然这是一个双指针的问题。同向双指针。有点困难的地方是j指针如何前进。我测试后是这样操作的。首先当i的值为第三个值(跟a,b都不相等),j等于i-1。然后要考虑j前进太快的问题(tree[j-1]==tree[j]),所以需要一个while循环保证区间最大。举一个例子:[0,1,6,6,4,4,6],这种情况下j的二次更新的时候为3但是很明显tree[2]=tree[3],也就是说j–的区间肯定比较大。

题解
class Solution {
public:
    int totalFruit(vector<int>& tree) {
        if(tree.size()==0)
        return 0;
        int i=1;
        int j=0;
        int ans=0;
        int temp;
        int a=-1,b=-1;//分别表示两个篮子的水果种类
        for(i;i<tree.size();i++){//ab初始化
            a=tree[j];
            if(tree[i]!=tree[j]){
                b=tree[i];
                break;
            }
        }
        if(b==-1)//tree里面只有一种水果
        return tree.size();
        for(i;i<tree.size();i++){
            if((tree[i]!=a&&tree[i]!=b)){
                temp=i-j;
                ans=max(ans,temp);
                j=i-1;
                while(tree[j-1]==tree[j])//j指针后退保证区间最大
                j--;
                a=tree[j];
                b=tree[i];
            }
            if(i==tree.size()-1){
                temp=i-j+1;
                ans=max(ans,temp);
            }
        }
        return ans;
    }
};

这个是测试过正确的代码,这个题目的难度是中等。题目需要考虑的特殊情况有两点:1.考虑tree为空。2.考虑tree里面只有一种水果。
写代码还是要考虑周全每种情况。每次都是通过测试来发现错误这样不好。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值