Java 实现和为S的连续正数序列

输出所有和为S的连续正数序列。

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

代码

    public static List<List<Integer>> findContinuesSequence(int target) {
        // 至少包含两个数,所以最小也得是3,这样还有{1,2}一个组合满足
        if (target < 3) {
            return null;
        }
        // 初始化两个指针
        int small = 1;
        int big = 2;
        // 获取目标值的一半
        int middle = (target + 1) / 2;
        // 保存结果
        List<List<Integer>> result = Lists.newArrayList();
        // small < middel,因为big比small大,超过middle,small+big > target
        // 等于也不可以,small+big>target
        // 比如14,middel=7,如果small=7,big > small,small+big > target
        // 所以所有结果的起始点应该在middle的左侧
        int sum = small + big;
        while (small < middle) {
            /* 这是自己的写法
            int sum = 0;
            for (int i = small; i <= big; i++) {
                sum += i;
            }
            if (sum == target) {
                result.add(Lists.newArrayList(small, big));
                big++;
            } else if (sum > target) {
                small++;
            } else {
                big++;
            }
            */
            // 如果和大于target,则减去较小的值small, 并移动small的指针,使得sum <= target
            // sum <= target时,终结此次while
            // sum > target时,减小范围,移动small的指针,此时需要减去大于target的部分
            // sum = target时,记录此次结果,并且移动big的指针,扩大查找范围
            // sum < target时,扩大范围,移动big的指针,此时需要更大的值来弥补和target的差距
            // 比如 target = 15,  small=1, big = 2
            //     sum = 1+2 =3,           sum < target, small=1, big = 3
            //     sum = 1+2+3 = 6,        sum < target, small=1, big = 4
            //     sum = 1+2+3+4 = 10,     sum < target, small=1, big = 5
            //     sum = 1+2+3+4+5 = 15,   sum = target, 找到, 扩大搜索范围, small=1, big = 6
            //     sum = 1+2+3+4+5+6 = 21, sum > target, small=2, big = 6
            //     sum = 2+3+4+5+6 = 20,   sum > target, small=3, big = 6
            //     sum = 3+4+5+6 = 18,     sum > target, small=4, big = 6
            //     sum = 4+5+6 = 15,       sum = target, , 找到, 扩大搜索范围, small=4, big = 7
            //     sum = 4+5+6+7 = 22,     sum > target, small=5, big = 7
            //     sum = 5+6+7 = 18,       sum > target, small=6, big = 7
            //     sum = 6+7 = 13,         sum < target, small=6, big = 8
            //     sum = 6+7+8 = 21,       sum > target, small=7, big = 8
            //     sum = 7+8 = 15,         sum = target, , 找到, 扩大搜索范围, small=7, big = 9
            //     sum = 7+8+9 = 24,       sum > target, small=8, big = 9
            //     middel = (15 + 1) / 2 = 8, 不满足small < middle,退出
            while (sum > target && small < middle) {
                sum -= small;
                small++;
                if (sum == target) {
                    result.add(Lists.newArrayList(small, big));
                }
            }
            big++;
            sum += big;
        }
        return result;
    }

猜你喜欢

转载自blog.csdn.net/zl18310999566/article/details/80245450
今日推荐