offer52的題目要求是:輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,使得他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。
當然,即便輸入的不是乙個遞增排序的陣列,我們也可以sort一下變成乙個完成排序的陣列。陣列的遞增性給我們帶來了許多便利,比如我們可以用雙指標從頭和結尾開始遍歷:
# offer52-solution
class
solution
:def
findnumberswithsum
(self, array, tsum):if
not array:
return
head =
0 tail =
len(array)-1
a = b = tsum
while
(head != tail)
:if array[head]
+array[tail]
< tsum:
head = head +
1elif array[head]
+array[tail]
> tsum:
tail = tail -
1else
:if array[head]
*array[tail]
<= a*b:
a,b = array[head]
,array[tail]
head = head +
1if a*b == tsum*tsum:
return
return
[a,b]
儘管不是offer52的要求,我們來簡單討論一下三數之和。要求和上述一樣:輸入乙個遞增排序的陣列,判斷陣列中是否存在三個數之和為0,若是,輸出該三個數。為了簡單起見,即便存在多組解,我們只輸出一組即可。
其實原題目給出的陣列並不是遞增的,但是反正我們sort一下夜不費事——排序是為了讓元素之間呈現出某種規律,使得後續的處理會簡單很多,這就是所謂的沒有規律就要創造規律了。題目的要求是三個數之和為0,這樣可以方便我們使用正數+負數的技巧。**我自己沒有寫,參考:
lintcode三數之和系列問題
# offer52*-solution
# the sum of three nums
class
solution
:def
threesum
(self, nums)
:"""
:type nums: list[int]
:rtype: list[list[int]]
"""nums.sort(
) count =
len(nums)
collect =
for i in
range
(count)
: left = i+
1 right = count-
1#避免重複找同乙個資料
if i >
0and nums[i]
== nums[i-1]
: left +=
1continue
#資料按小到大排列,每次選取nums[i],在其後尋找符合a + b + c = 0的兩個資料
while left < right:
sum= nums[i]
+ nums[left]
+ nums[right]
ifsum==0
: col =
[nums[i]
,nums[left]
,nums[right]
] left+=
1 right-=
1#迴圈中nums[i]已確定,當再確定1個數時,另乙個數也確定,左右端任一端出現重複均可跳過
while nums[left]
== nums[left-1]
and left < right:
left+=
1while nums[right]
== nums[right+1]
and left < right:
right-=1if
sum<0:
left+=
1elif
sum>0:
right-=
1return collect
兩數之和,三數之和
兩數之和 方法一 暴力 throw new illegalargumentexception 時間複雜度 o n 2 空間複雜度 o 1 public int twosum int nums,int target throw newillegalargumentexception no twosum...
《劍指offer》 52 構建乘積陣列
題目 給定乙個陣列a 0,1,2.n 1 請構建乙個陣列b 0,1,2,n 1 使b中的元素b i a 0 a 1 a i 1 a i 1 a n 1 不能使用除法。解決思路 通過正反兩次來求b i 正著 b i a 0 a i 1 反著 temp b n b i 1 最後通過b i temp就可以...
兩數之和 三數之和 四數之和
兩數之和意思就是 給你乙個陣列,從中找出兩個數字,讓他們的和等於乙個具體的target。找到所有這樣的兩個數。並且這兩個數字不能完全一樣。n數之和的意思是 給你乙個陣列,從中找出n個數字,讓他們的和等於乙個具體的target。找到所有這樣的n個數。並且這n個數字不能完全一樣。最基礎的,也是最關鍵的就...