《劍指offer》之和爲S的連續正數序列

前言

今天刷的一道題目是是關於窮舉的。

題目

小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和爲100(至少包括兩個數)。沒多久,他就得到另一組連續正數和爲100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和爲S的連續正數序列? Good Luck!

輸出描述:

輸出所有和爲S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序

分析

這裏參考了答案區的思路,這個思路算是很厲害的,窗口的雙指針的思路。窗口的左右兩邊就是兩個指針,我們根據窗口內值之和來確定窗口的位置和寬度。
以sum=15爲例吧,
初始left=1;right=2;和add=1+2=3;
add<sum,所以right++;
所以add=1+2+3=6;
還是add<sum,right++
在這裏插入圖片描述
到right=5時,
add=1+2+3+4+5=15;剛好等於15,所以這一組是我們求的。我們繼續
left++,
所以此時left=2,right=5;
在這裏插入圖片描述
此時add=2+3+4+5=14;
add<sum;所以right++;
此時right=6,add=2+3+4+5+6=20;
add>sum,所以left++,
此時left=3,add=3+4+5+6=18;
add>sum,所以left++,
此時left=4,add=4+5+6=15;
add=sum ,將這組記錄下來,繼續left++;
此時left=5,rigt=6;add=5+6=11;
add<sum;所以right++;
此時right=7,add=5+6+7=21;
add>sum,所以left++,
此時left=6,rigt=7;add=6+7=14;
add<sum;所以right++;
此時left=6,rigt=8;add=6+7+8=21;
add>sum,所以left++,
此時left=7,rigt=8;add=7+8=21;
add=sum ,將這組記錄下來,繼續left++;
此時left=8,rigt=8;left>=right,循環結束退出,這時我們就可以得到三組滿足條件的序列啦。

通過上面的例子,思路算是非常清楚了,主要是左右兩個指針,當left<right 就執行循環體。循環體做的事情就是,先求left加到right 的和。

add=(left+right)*(right-left+1)/2; 

這個求和很好算吧,等差數列就和

add=(a1+an)*n/2
a1=left;
an=right;
n=right-left+1;
代替上去就可以了。

然後就比較add 與sum 的大小,如果add< sum ,則右指針right右移一位,如果add>sum,則左指針右移一位,如果add=sum,就表明該組是我們想要的,記錄下來,同時l左指針右移一位,繼續查找其他。
當left>=right的時候就退出循環體。

解法

public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer> >  lists = new ArrayList<> ();
        int left=1;
        int right=2;
        while(left<right){
            int add=(left+right)*(right-left+1)/2;
            if(add==sum){
                ArrayList<Integer> list=new ArrayList<>();
                for(int i=left;i<=right;i++){
                    list.add(i);
                }
                lists.add(list);
                left++;
            }else if(add<sum){
                right++;
            }else {
                left++;
            }
        }
        return lists;
    }

測試

main 方法

public static void main(String[] args) {
        Solution solution= new Solution();
        ArrayList<ArrayList<Integer>> lists=solution.FindContinuousSequence(15);
        for(ArrayList<Integer> list:lists){
            for(Integer tmp:list){
                System.out.print(tmp+"\t");
            }
            System.out.println();
        }
    }

在這裏插入圖片描述
再測一個100的
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章