数据结构与算法--有序数组中找出和为s的两个数字
生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法--有序数组中找出和为s的两个数字
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有序數組中找和為s的兩個數字
題目:輸入一個遞增排序的數組array, 和一個數字s, 在數組中找出兩個數,使得這兩個數的和是s,如果有多對,輸出一對即可。
最簡單方案
- 雙循環,每次獲取一個數據,和數組中其他數據求和,與s比較,此方法最直觀,時間復雜度是O(n2),比如必然會有更優解
優化方案一
-
既然要找兩個數字,而且是數組,第一感覺就是雙指針的策略,分析如下
- 既然要找兩個數字,那么假如我們隨機選兩個,如果和小于s,那么應該向后找,反之向前找
- 案例分析法{1,2,4,7,11,15},找和為15 的
- 初始化兩個指針分別指向 最后元素positionBig,指向第一個元素 positionSmall
- 如果兩個數據和正好是s,那么得到解
- 如果兩個數據和大于s,說明需要減少,那么應該positionBig –
- 如果兩個數據和小于s,說明需要增大,那么應該positionSmall++
- 如下圖:
-
如上分析有如下代碼
- 如上代碼中我們while循環的退出條件是 positionBig< positionSmall那么我們總共應該就是一次循環,時間福再度是O(n),不使用額外空間
變種題型,非有序數組
題目:輸入一個非有序數組array, 和一個數字s, 在數組中找出兩個數的組合,使得這兩個數的和是s,如果有多對,輸出多對即可。
- 因為沒有了有序的特性,我們無法用上題中的方案,最簡單辦法,先排序,在按上面的方法,這樣時間復雜度比如超過O(n)
- 另一中思路,空間換時間:
- 遍歷數組,并且將數組已經遍歷過的值k 存儲在hash中,存儲模式為 key = k, value = k,這樣可以用O(1)的時間拿到已經范問過的數據
- 每次遍歷數組中數據 n 時候,查找hash中 s-n
- 如果s-n 存在,那么在之前遍歷過的數據中存在與n 配對后和為s的數據,一次遍歷完數據,找到我們需要的所有配對:
- 以上解法借助了HashMap,所以在時間復雜度計算中需要考慮containsKey的開銷,如果出題人不讓用jdk相關的集合類,我們可以通過數組自己實現一個Hash。
更復雜的題型
類似題:輸入一個正數s,打印所有 和 為s的連續正數序列(至少含有2個數字),例如,輸入15,得到1+2+3+4+5 = 4+5+6=7+8,所以我們有打印出三個連續的序列1 ~ 5, 4 ~ 6, 7 ~ 8
-
按如上題目的解決思路,此處也是尋找和為s的值,只不過是N數據的和,并且沒有給出數字,那么案例中s=15,時候其實隱含的條件就是數組是 1~14 ,因為條件中都是正整數,那么有如下分析:
- 依然雙指針方法,因為此處我們需要找連續的數據,那么不能前后尋找,設positionBig = array.length,positionSmall = pogitionBig-1
- 如果positionSmall ~ positionBig 中所有數據和 為 s,那么得出正解,此時讓positionBig–,positionSmall = positionBig-1,繼續求解
- 如果positionSmall ~ positionBig中所有數據和 > s,那么說明數據和過大,我們應該減少大的值positionBig–
- 如果positionSmall ~ positionBig 中所有數據和 < s, 說明數據和 過小,我們擴大數據的基數,讓更多數據累加 positionSmall –
- 我們從后向前逐個逐個的查詢求和的組合,最后得到正解
- 如下圖所示:
-
第一個數列:
-
第二個數列:
-
第三個數列:
-
經如上分析有如下代碼:
- 如上實現代碼中我用雙指針的方式來做了一個類似雙循環的操作,每次找到解,則遞減一位,讓標記為從一個方向遍歷整個數組,時間復雜度O(n2)。
變種題型: 輸入一個正數s,打印所有 和 為s的元素的組合(至少含有1個數字),例如,輸入{1,2,3,4,5,6,7,8,9,10,11,12,13,14},9,得到如下
9 8,1 7,2 6,3 6,2,1 5,4 5,3,1 4,3,2-
解題分析:
- 如上案例分析中,存在不很多不連續的數列也可以符合組合求和的題目要求,因此連續查找的方式需要進行調整
- 還是延續上題中思路,找到第一個小于目標值的positionBig, 令positionSmall = positiomBig - 1
- 依次遍歷positionSmall ~ 0 ,并在臨時數組temp 保存positionBig值
- 令sum = positionSmall + sum(temp),
- 當sum > s,說明當前數據過大,需要減小,執行positionSmall –
- 當sum < s ,說明當前數據過小,但是可能符合要求,將positionSmall 添加到temp,執行positionSmall –
- 當sum = s ,符合題解,將當前temp 添加到resultList隊列中得到一組解,并且執行positionSmall –
- 依次執行如上流程,直到positionSmall < 0,執行positionBig –
- 查找退出條件 positionBig < 0
-
經如上分析有如下代碼:
上一篇:數據結構與算法–數組中出一次的數字
下一篇:數據結構與算法–翻轉單詞順序
總結
以上是生活随笔為你收集整理的数据结构与算法--有序数组中找出和为s的两个数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泥灸可以减肥吗
- 下一篇: 拔罐减肥一个月可以瘦20斤吗