給出若干個整數,詢問其中是否有一對數的和等於給定的數。
共三行:
第一行是整數n(0 < n <= 100,000),表示有n個整數。
第二行是n個整數。整數的範圍是在0到10^8之間。
第三行是乙個整數m(0 <= m <= 2^30),表示需要得到的和。
若存在和為m的數對,輸出兩個整數,小的在前,大的在後,中間用單個空格隔開。若有多個數對滿足條件,選擇數對中較小的數更小的。若找不到符合要求的數對,輸出一行no。
4
2 5 1 4
6
1 5
中等,查詢
解法採用二分查詢,首先對陣列從小到大排序,複雜度o(nlogn),從頭到尾處理陣列中的每個元素l[i],在大於l[i]的數中二分查詢是否存在乙個等於 expectsum - l[i]的數,複雜度也是o(nlogn)。兩部分相加,總複雜度仍然是o(nlogn)。
採用尺取法,首先對陣列從小到大排序;然後,設定兩個變數i和j,分別指向頭和尾,i初值是0,j初值是n-1,然後讓i和j逐漸向中間移動,檢查l[i]+l[j],如果大於預期值,就讓j減1,如果小於預期值,就讓i加1,直至l[i]+l[j] = expectsum。排序複雜度o(nlogn),檢查的複雜度o(n),合起來總複雜度o(nlogn)。
二分法
def
search()
: n =
(int)(
input()
) l =
a =input()
b = a.split(
" ")
expectsum =
(int)(
input()
)for i in
range
(n):
(int
)(b[i]))
l.sort(
) i =
0while
(true):
left = i+
1 right = n-
1while
(left<=right)
: mid = left +
int(
(right-left)/2
)if(l[i]
+l[mid]
>expectsum)
: right = mid -
1elif
(l[i]
+l[mid]
:
left = mid +
1else
:print
(l[i]
,l[mid]
)return
i = i+
1search(
)
尺取法
def
search()
: n =
(int)(
input()
) l =
a =input()
b = a.split(
" ")
expectsum =
(int)(
input()
)for i in
range
(n):
(int
)(b[i]))
l.sort(
) i =
0 j = n-
1while
(i:sum
= l[i]
+l[j]if(
sum>expectsum)
: j = j-1if
(sum
: i = i+1if
(sum
== expectsum)
:print
(l[i]
,l[j]
)return
search(
)
二分演算法 尋找指定和的整數對
輸入n n 100,000 個整數,找出其中的兩個數,它們之和等於整數m 假定肯定有解 題中所有整數都能用 int 表示 解法1 用兩重迴圈,列舉所有的取數方法,複雜度是o n 2 的。for int i 0 i n 1 i for int j i 1 j n j if a i a j m brea...
演算法實踐 派 (二分)
林克被造的紀念日快要到了。根據任天堂公司的慣例,每年到這個時間都會一些蛋糕分給林克的朋友。這些蛋糕有不同的口味,比如南瓜蛋糕 堅果蛋糕 西瓜蛋糕 胡蘿蔔蛋糕 水果蛋糕等等 有n種不同口味,大小不同的蛋糕 為了公平,每個朋友都會分到一塊大小相同的蛋糕 不需要同樣形狀,但是要同一種口味,不允許混合口味,...
演算法實踐 農夫和牛 (二分)
農夫john建造了一座很長的畜欄,它包括n 2 n 100,000 個隔間,這些小隔間的位置為x0,xn 1 0 xi 1,000,000,000,均為整數,各不相同 john的c 2 c n 頭牛每頭分到乙個隔間。牛都希望互相離得遠點省得互相打擾。怎樣才能使任意兩頭牛之間的最小距離盡可能的大,這個...