和為S的連續序列(雙指標 滑動視窗)

2021-09-25 19:39:40 字數 1532 閱讀 9211

鏈結:和為s的連續序列

題目詳情

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

分析

很容易得到乙個o(n

2)o(n^2)

o(n2

)暴力演算法,但我們可以觀察得到結論:

發現每次列舉起點後,j做了很多次無用功的「回溯操作」,那麼我們要找乙個比較合適的起點開始檢索,有點類似於kmp演算法思想的意味

從起點看呢,每次我們找到乙個答案後i++,假設上次的區間長度是k,下次找到的區間長度最多只能是k-1,原因是每次移動起點i整個區間每個位置+1,即和至少多了k,為了扣回來,一定是起點至少往後多走1格;

綜上,我們可以考慮用雙指標來維護這個區間操作,複雜度o(n

對於這種雙指標做法也稱為尺取法,還有一種寫法是《挑戰程式設計競賽》中的方法:每次找乙個起點後再巢狀乙個迴圈找到終點的極限值,並把和儲存住,以後就省去計算等差數列的步驟,以後就只是對存住的值進行加減,在某些不能寫出通項公式的問題中這種做法更優,效率也比較高。法一要避免這種多次計算也可以預處理字首和

對於法二尺取法的更新答案操作一般是在整個迴圈的最後,相當於做了這一次指標移動後的一次總結,而法一就要每次移動都要judge一次

code

//法一

class

solution

else

if(tmp < sum)

else

}return ans;

}

vector<

int>

number

(int l,

int r)

return d;}}

;

//法二

class

solution

return ans;

}

vector<

int>

number

(int l,

int r)

return d;}}

;

對於這個問題還有另外一種問法:對於乙個任意的自然數,問是否能將其拆分成2個或2個以上的連續自然數之和,寫出所有的等式,這是程式設計之美的乙個問題,關於做法有人給出部分的證明戳這裡

Q41 和為S的連續正數序列 雙指標 滑動視窗

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

和為S的連續正數序列 滑動視窗

輸出所有和為s的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序。一開始只想到了最粗暴的窮舉解法 因為s 2後,數字相加一定大於s,所以迴圈只到s 2為止 public arraylist findcontinuoussequence int sum else if curs...

( )41 和為S的連續正數序列 滑動視窗

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