劍指Offer對答如流系列 和為s的數字

2021-10-02 11:23:25 字數 2165 閱讀 9459

問題(1)和為s的兩個數字

輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,使得它們的和正好是s。如果有多對數字的和等於s,輸出任意一對即可。

問題(2)為s的連續正數序列

輸入乙個正數s,列印出所有和為s的連續正數序列(至少含有兩個數)。例如輸入15,由於1+2+3+4+5=4+5+6=7+8=15,所以結果列印出3個連續序列1~5、4~6和7~8。

問題(1)

考慮到數列遞增,我們設定兩個頭尾兩個索引i和j,

若ai + aj == sum,就是答案(相差越遠乘積越小)

若ai + aj > sum,aj肯定不是答案之一(前面已得出 i 前面的數已是不可能),j -= 1

若ai + aj < sum,ai肯定不是答案之一(前面已得出 j 後面的數已是不可能),i += 1

由於是從兩邊往中間移動,所以不會有跳過的情況,時間複雜度為o(n)。

問題(2)

順著問題(1)的思路來就是

當從i到j的序列的和小於sum時,增加j,使序列包含更多數字;(記得更新序列之和)

當從i到j的序列的和大於sum時,減少i,使序列去掉較小的數字;(記得更新序列之和)

當從i到j的序列的和等於sum時,此時得到乙個滿足題目要求的序列,輸出,然後繼續將i增大,往後面找新的序列。

序列要求最少兩個數字,因此,當i到了sum/2時,就可以結束了。

不過,問題(2)也可以不借鑑問題(1)的思路,採用數學分析法

對於乙個長度為n的連續序列,如果它們的和等於s,有:

當n為奇數時,s/n恰好是連續序列最中間的數字,即n滿足 (n&1)==1 && s%n==0

當n為偶數時,s/n恰好是連續序列中間兩個數字的平均值,小數部分為0.5,即n滿足 (s%n)*2==n (判斷條件中包含了n為偶數的判斷)

得到滿足條件的n後,相當於得到了序列的中間數字s/n,所以可以得到第乙個數字為 (s / n) - (n - 1) / 2,結合長度n可以得到所有數字。

此外,要考慮在什麼範圍內找n: 我們知道n至少等於2,那至多等於多少?n最大時,序列從1開始,根據等差數列的求和公式根據等差數列的求和公式:s = (1 + n) * n / 2,可以得到n應該小於sqrt(2s),所以只需要從n=2到sqrt(2s)來判斷滿足條件的n,繼而輸出序列。

問題(1)

public arraylist

findnumberswithsum

(int

array,

int sum)

int low=0;

int high=array.length-1;

while

(lowelse

if(array[low]

+array[high]

else

}return list;

}

問題(2)

思路一:

public arraylist

>

findcontinuoussequence

(int sum)

int small =1;

int big =2;

int cursum = small+big;

while

(small <= sum/2)

sequencelist.

add(sequence)

; cursum-=small;

small++

;//這兩行位置先後要注意}if

(cursum < sum)

if(cursum > sum)

}return sequencelist;

}

思路二:

public arraylist

>

findcontinuoussequence

(int sum)

for(

int n=

(int

) math.

sqrt(2

*sum)

; n>=

2; n--

) sequencelist.

add(sequence);}

}return sequencelist;

}

劍指Offer對答如流系列 醜數

我們把只包含質因子2 3和5的數稱作醜數 ugly number 求按從小到大的順序的第n個醜數。例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。判斷乙個數是不是醜數,最容易想到的方法就是讓這個數不斷除以2,3,5。對於第n個醜數,只要從1開始,依次判斷每個數是不...

劍指Offer對答如流系列 剪繩子

給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到最大的乘積18。遇到問題,先分析問題,由分析的結果確定所運用的演...

劍指Offer對答如流系列 包含min函式的棧

定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的min函式。在該棧中,呼叫min push及pop的時間複雜度都是o 1 push 和 pop均容易實現。主要就是min函式的定義,如果要通過操作push和pop操作獲取最小元素時間複雜度為o 1 基本上是不可能的。如果我們另外定義乙個成員...