剑指 Offer 57 - II. 和为s的连续正数序列

题目描述

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1:

输入:target = 9
输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof

代码

class Solution {
    public int[][] findContinuousSequence(int target) {
        // 由其特点,j 最多到 (target+1)/2,减少不必要的运算
        int len=(target+1)/2, j=2,i=1;
        List<int[]> n = new ArrayList<>();
        while (j <= len) {
            // 连续从 i 到 j 的总和
            int sum = (i+j)*(j-i+1)/2;
            // 如果sum < target,由 j 一直探索(扩张总和),直到 sum >= target
            while (sum < target && j<=len) {
                // 一开始我提交计算用的 sum = (i+j)*(j-i+1)/2;nt了,直接先对j++再sum += j就行了
                // 直接导致我多耗时2ms, ****
                j++;
                sum += j;
            }
            // 如果 sum > target 开始由 i 一直探索(缩小总和),直到 sum <= target
            while (sum > target && j<=len) {
                // 一开始我提交计算用的 sum = (i+j)*(j-i+1)/2;nt了,直接先减去i再对i++就行了
                sum -= i;
                i++;
            }
            if (sum == target) {
                n.add(getArray(i, j));
                // 再次尝试扩张
                j++;
            }
        }
        // 这个转换方法有点晦涩 T[] = List.toArray(new T()) ,这里 T = int[] 
        return n.toArray(new int[n.size()][]);
    }
    /**
     * 返回从 x 到 y 连续的数组:如 x=2, y=5, 返回 new int[]{2, 3, 4, 5}
     */
    private int[] getArray(int x, int y) {
        int len = y-x+1;
        int[] array = new int[len];
        int j=0;
        for (int i=x; i<=y; i++) {
            array[j++] = i;
        }
        return array;
    }
}


作者:li-qiu-shui
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/bu-yong-shuang-zhi-zhen-nan-ding-by-li-q-ov6f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 57 - II. 和为s的连续正数序列

C++双指针

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        int i=1,j=2;
        int mid=(target+1)/2;
        vector<vector<int>> res;
        int sum;
        while(j<=mid&&i<j){
            sum=(i+j)*(j-i+1)/2;
            if(sum==target){
                vector<int> arr;
                for(int k=i;k<=j;k++){
                    arr.push_back(k);
                }
                res.push_back(arr);
                i++;
            }
            else if(sum<target) j++;
            else i++;
        }
        return res;
    }
};
上一篇:冒泡排序


下一篇:57_初识Java_数组的引入_学习