鏈結:和為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。現在把問題交給你,你能不能也很快的找出所有和...