劍指offer 和為S的連續正數數列

2021-10-07 12:23:59 字數 1949 閱讀 7235

劍指offer——輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,使得他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。

咋一看好像是有點類似,共同點:遞增正數列、和一定。(emmmmm.... 那有怎樣呢?)

此時你可能會問:「之前的那道題不是才兩個數嗎? 這道題你怎麼知道有幾個數」,的確,這道題是正數序列,但是這題的正數序列有乙個明顯特徵:連續。連續的正數,也是公差為1的等差數列唄,這樣我們就可以將連續數列的和轉換為兩個數的和,s=(首項+尾項)*項數/2=(low+high)*(high-low+1)/2;這樣我們就將多個數的和,轉換為只跟首尾兩個數有關了,那我們怎麼確定首尾呢?我們之前的夾逼法,在判斷兩個數的和與s之間的大小關係的時候,若大於s,high--,r若小於s,low++;那這道題是否也採用夾逼的方法進行解決呢?很明顯不可以,為什麼呢?因為當low+high>s時,讓low+high更接近s的方法,只可能是high--;但是這道題,當low+high>s時,正數數列的和更接近s的方法有兩個:high--或low++; 在與s比較的時候,不能確定是high--還是low++。所以夾逼方法在這是不可行的。

此時我們應該轉換一下思路,在兩個數相加的的時候,我們是通過high--或low++的方式,不管是high--還是low++,都是在最小化的逼近s。那麼,我們在正數序列中元素的個數不確定的情況下,如何讓每一次與s判斷之和的操作更加逼近s呢?

/**

* @param sum

* @return 輸出所有和為s的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序

*/private static arraylist> findcontinuoussequence(int sum)

list.add(arraylist);

high++; //為了輸出所有的結果,在這做low++或high++操作,使得首尾指標發生改變,求出其他滿足條件的情況。

}else if (res < sum) else

}return list;

}

無論是求兩個和為s的兩個數,還是求和為s的正數序列,共同的思路都是轉換為首尾指標的變化,通過首尾指標的變化來使和緩慢接近s,直到相等。

第二種方法是根據本題的特徵加上數學的方法得到的。觀察可以很容易得到,當正數序列的個數為奇數或偶數時,都會有其特徵。當序列個數為奇數時,很明顯18,19,20,21,22序列中,中位數與平均數相等,也就是說當序列個數為奇數時,只需要知道序列的個數就可以得到完整序列。

當序列為偶數時,中間兩個數相加的和乘以項數就等於s;

根據以上,方法也可以得到正確的解答,**如下:

private static arraylist> findcontinuoussequence(int sum) 

arraylistarraylist = new arraylist();

//j的初始值,也就是首項不能小於0,在上面已經作校驗

for (int j = mid - temp + 1; j <= mid+temp; j++)

list.add(arraylist);

}else

else

arraylistarraylist = new arraylist();

for (int j = mid - temp; j<= mid+temp; j++)

arraylist.add(j);

}list.add(arraylist);}}

} return list;

}

可能大部分人第一想到的就是方法二吧,純數學思想,也很簡單,但是要考慮到邊界條件,不然會有bug。

劍指offer 和為S的連續正數序列

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

劍指offer 和為S的連續正數序列

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

劍指offer 和為 s 的連續正數序列

輸入乙個正數 s,列印出所有和為 s 的連續正數序列 至少兩個數 例如輸入 15,由於 1 2 3 4 5 4 5 6 7 8 15,所以結果打出 3 個連續序列 1 5 4 6 和 7 8。考慮用兩個數 small 和 big 分別表示序列的最小值和最大值。首先把 small 初始化為 1,big...