17.12 設計乙個演算法,找出陣列中兩數之和為指定值的所有整數對。
時間複雜度o(n)的解法
我們可以用乙個雜湊表或陣列或bitmap(後兩者要求陣列中的整數非負)來儲存sum-x的值, 這樣我們就只需要遍歷陣列兩次即可找到和為指定值的整數對。這種方法需要o(n) 的輔助空間。如果直接用陣列或是bitmap來做,輔助空間的大小與陣列中的最大整數相關, 常常導致大量空間浪費。比如原陣列中有5個數:1億,2億,3億,4億,5億。sum為5億, 那麼我們將bitmap中的sum-x位置1,即第4億位,第3億位,第2億位,第1億位,第0位置1. 而其它位置都浪費了。
如果使用雜湊表,雖然不會有大量空間浪費,但要考慮衝突問題。
時間複雜度為o(nlogn)的解法
我們來考慮一種空間複雜度為o(1),而且實現也很簡單的演算法。首先,將陣列排序。 比如排序後得到的陣列a是:-2 -1 0 3 5 6 7 9 13 14。然後使用low和high 兩個下標指向陣列的首尾元素。如果a[low]+a[high] > sum,那麼說明a[high] 和陣列中的任何其它乙個數的和都一定大於sum(因為它和最小的a[low]相加都大於sum)。 因此,a[high]不會與陣列中任何乙個數相加得到sum,於是我們可以直接不要它, 即讓high向前移動一位。同樣的,如果a[low]+a[high] < sum,那麼說明a[low] 和陣列中的任何其它乙個數的和都一定小於sum(因為它和最大的a[high]相加都小於sum)。 因此,我們也可以直接不要它,讓low向前移動一位。如果a[low]+a[high]等於sum, 則輸出。當low小於high時,不斷地重複上面的操作即可。
c++實現**:
#include#include#include
using
namespace
std;
vector
int> > getsum(vector &num,int
target)
); j--;
i++;
}else
if(num[i]+num[j]else
if(num[i]+num[j]>target)
}return
res;
}int
main()
; vector
int> > res=getsum(numbers,8
);
for(auto a:res)
}
careercup 中等難度 17 7
17.7 給定乙個整數,列印該整數的英文描述 例如 one thousand,two hundred thirty four 解法 舉個例子,在轉換19 323 984時,我們可以考慮分段處理,沒三位轉換一次,並在適當的地方插入 thousand 千 和 million 百萬 也即,convert ...
careercup 中等難度 17 8
17.8 給定乙個整數陣列 有正數和負數 找出總和最大的連續序列,並返回總和。解法 就是求連續子串行的和最大,不過存在乙個問題 假設整個陣列都是負數,怎麼樣才是正確的行為呢?看看這個簡單的陣列,一下答案每個都可以說的通 3 假設子串行不能為空 0 子串行的長度為空 int min 視為錯誤的情況 我...
careercup 高等難度 18 2
18.2 編寫乙個方法,洗一副牌。要求做到完美洗牌,換言之,這幅牌52!種排列組合出現的概率相同。假設給定乙個完美的隨機發生器。解法 假定有個陣列,含有n個元素,類似如下 1 2 3 4 5 利用簡單構造法,我們不妨先問自己,假定有個方法shuffle 對n 1個元素有效,我們可以用它來打亂n個元素...