目錄
一、 解法一
二、 解法二
三、 解法三
四、 解法四(換元法)
五、 解法五
要求計算出9~16的和,寫出正確答案是100。究竟有多少種連續的正數序列的和為100(至少包括兩個數)。另一組連續正數和為100的序列:18,19,20,21,22。現有問題如下,能不能也很快的找出所有和為s的連續正數序列?
輸出所有和為s的正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序。
數學知識偏多一點,但也不是難到無法求解,稍微麻煩一點就是了。首先我們需要回答三個問題。
n = 2k + 1時,n項連續正數序列的和為s的條件:n & 1 && s / n == 0解讀 邏輯與的左邊要求n為奇數,右邊要求整個序列的平均數恰好為中間數。n = 2k時,n項連續正數序列的和為s的條件:s % n * 2 == n解讀 s % n 的結果是中間兩項左邊的那項,乘2剛好是項數。舉例,現有s = 39,6個連續正數序列和式能不能為s呢?套用公式,39 % 6 * 2 =6 == 6,我們也知道,這次的序列是 4、5、6、7、8、9,取餘的結果為3對應著值為6的那一項,也就是中間項左邊的那一項。
和為s,項數為n,如何寫出這個序列?s / n - (n-1) / 2解讀 執行的除法是地板除法(floor),不管最終結果有無小數都直接捨去。仍使用上述例子,39 / 6 = 6,6恰好是中間項左邊的那一項,6 - (6-1)/ 2 = 4,恰好是序列最左端。序列寫出來就沒問題。
class solution
}return allres;}};
還有一點需要注意,s = (a0 + a0 +n-1)* n / 2,等差序列公式自然是不必說的。對其進行放縮,就有s > n平方 / 2;即n < 根號2s(這一點在解法4中也有涉及)。這樣做的話可以減少遍歷次數。 在for迴圈中就有體現。
for (int n = sqrt(2 * sum); n >= 2; --n)時間複雜度為o(根號sum )。
暴力求解,類似於tcp的滑動視窗協議。
class solution
else //如果當前視窗內的值之和大於sum,左窗框左移一下
low++;
}return allres;}};
同樣是受到了tcp滑動視窗協議的啟發。還有迭代的想法在裡面,也可以是說狀態轉移方程。
用begin和end分別表示序列的左值和右值,首先將begin初始化為1,end初始化為2;
class solution
if(cur == sum && begin < end) //防止出現某個陣列只有1項的情況
根據所學知識,有:
(a + b)(b - a + 1) = 2 * sum;此為等差數列公式。
令i= b - a + 1(項數), j = a + b(首末項之和);現討論取值範圍。i >= 2(序列中至少有2項), j >= 3(序列之和至少為3);隱藏的關係是:j > i同時還有i * j = 2 * sum,進行放縮之後就有i * i< 2 * sum,即 i < 根號(2 * sum)。對i進行遍歷,找出i,j∈正整數且j - i + 1為偶的取值。
突破口仍然是先求出項數,然後求出序列第一項;與解法一相差不大。但具體細節上還有較大差異。
和為S的連續正數序列
題目描述 小明很喜歡數學,有一天他在做數學作業時,要求計算出9 16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100 至少包括兩個數 沒多久,他就得到另一組連續正數和為100的序列 18,19,20,21,22。現在把問題交給你,你能不能也很快的...
和為S的連續正數序列
小明很喜歡數學,有一天他在做數學作業時,要求計算出9 16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100 至少包括兩個數 沒多久,他就得到另一組連續正數和為100的序列 18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和...
和為S的連續正數序列
小明很喜歡數學,有一天他在做數學作業時,要求計算出9 16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100 至少包括兩個數 沒多久,他就得到另一組連續正數和為100的序列 18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和...