和为S的连续正数序列 剑指offer

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

   
    /**
     * 思路1:针对序列起始数字。
     * 从start=1开始循环,假设序列的起始数字为start,那么用S逐渐减去start,start+1,star+2....
     * 最后S会为0。若S最后为0,则说明以该start开始的序列是和为S的连续序列;若最后S小于0,则 
     * start+1,再按上述步骤继续下去。 时间复杂度较高
     * */
    public ArrayList<ArrayList<Integer> > FindContinuousSequence1(int sum) {
        ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> list;
        int start;
        for (start = 1 ; start<= sum/2;start++){
            int temp = sum;
            int step = start;

            while (temp > 0){
                temp -= step;
                step++;
            }
            if (temp==0){
                list = new ArrayList<>();
                for (int i = start; i < step; i++) {
                    list.add(i);
                }
                lists.add(list);
            }
        }
        return lists;
    }
    /**
     * 思路2:针对序列长度
     * 假设序列长度为n。由于序列是公差为1的等差数列,所以S=n(n+1)/2.从而n< √2S
     * 若n为奇数,则序列中间数就是整个序列的平均值,有 (n & 1) == 1 && sum % n == 0;
     * 如果n为偶数,则序列中间两个数的平均值是序列的平均值,有(sum % n) * 2 == n.
     * */

    public ArrayList<ArrayList<Integer> > FindContinuousSequence2(int sum) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
        for (int n = (int) Math.sqrt(2 * sum); n >= 2; n--) {
            if ((n & 1) == 1 && sum % n == 0 || (sum % n) * 2 == n) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int j = 0, k = (sum / n) - (n - 1) / 2; j < n; j++, k++) {
                    list.add(k);
                }
                ans.add(list);
            }
        }
        return ans;
    }

    /**
     * 思路3:定义两个指针 low、high,分别指向序列的起始和终止
     * 初始:low=1,high=2
     * 循环:利用等差数列的性质: S=(low+high)*(high-low+1)/2 比较sum和S的值
     *      当 low<high 
     *      如果S<sum,则增大high
     *      如果S>sum,则增大low
     *      如果S=sum,则将low与high之间(包括low和high)的数插入list中,然后low增大
     *      
     * */
    public ArrayList<ArrayList<Integer> > FindContinuousSequence3(int sum) {
        ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> list;
        int low=1,high=2;
        while (low<high){
            int temp = (low+high)*(high-low+1)/2;
            if (temp == sum){
                list = new ArrayList<>();
                for (int i = low; i <= high ; i++) {
                    list.add(i);
                }
                lists.add(list);
                low++;
            } else if (temp<sum){
                high++;
            } else {
                low++;
            }
        }
        return lists;
    }

猜你喜欢

转载自blog.csdn.net/fendianli6830/article/details/81167191