滑动窗口问题的详解

滑动窗口技术就是我们日常所说的“双指针”,利用一前一后两个指针,通过对限定条件的判断,调整两个指针的相对位置,来达到我们的要求。

Talk is cheap,Show me the code。接下来让我们直接进入到实战演练环节。’

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

我们首先稍微分析下思路,它要求我们输出所有和为S的连续正数数列,注意这里有两个限定条件,首先是正数,其次是连续数列。我们能想到的最小的连续正数数列是什么?没错是1和2。其次他要求序列建开始数字由小到大,那么我们可以通过对1进行累加得到该数列。
下面是具体的解题思路

  • 创建一个二重ArrayList数组result作为我们的返回值
  • 将两个滑动指针赋初值,plow=1 phigh=2,同时phigh>plow是我们循环终止条件
  • 使用求和公式(phigh + plow) * (phigh - plow + 1) /2 判断公式结果和方法参数的大小情况
  • 相等 new出一个list,把plow到phigh的值全部添加,然后将这个list加入result
  • 小于 说明我们的数字不够大 phigh++
  • 大于 说明我们的数字太大 plow--

通过上述步骤,代码也就不难编写了。

public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {

        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        int plow = 1, phigh = 2;
        while (phigh > plow) {
            if ((phigh + plow) * (phigh - plow + 1) / 2 == sum) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int i = plow; i <= phigh; i++) {
                    list.add(i);
                }
                result.add(list);
                plow++;
            } else if ((phigh + plow) * (phigh - plow + 1) / 2 < sum) {
                phigh++;
            } else {
                plow++;
            }
        }
        return result;
    }

希望本篇文章对你有所帮助!!

猜你喜欢

转载自www.cnblogs.com/jiangtunan/p/11086951.html