兩數之和是一道很是經典,也很是高頻的面試題,題目大意以下:面試
給定一個整數數組nums
和一個目標值target
,請你在該數組中找出和爲目標值的那兩個整數,並返回他們的數組下標。
case:
給定nums = [2, 1, 7, 11, 15], target = 9
由於nums[0] + nums[2] = 2 + 7 = 9
因此返回[0, 2]
以前咱們探討了這個問題的暴力運算法和哈希表法,今天咱們使用雙指針法來解決它。算法
left
,right
兩個指針;target
與left
值加right
值的和,移動對應的指針;雙指針和快速排序、冒泡排序等具體算法不一樣。它更接近於一種思(tào)路,一種使用兩個指針互相配合來存儲節點以便於運算的技巧。數組
雙指針法適用於數組、鏈表等線性數據結構,經常使用的思路有:碰撞指針、滑動窗口、快慢指針等。數據結構
在兩數之和這個case中咱們使用碰撞指針的方式來實現,其它兩種套路會在後續文章中介紹。spa
所謂碰撞指針,是指在有序數組中定義left
(數組起始位置)、right
(數組終止位置)兩個指針,在遍歷時根據對應條件的不一樣來判斷應該移動哪一個指針,進而從數組兩端遍歷數組。3d
因此在兩數之和中咱們須要先將目標數組進行排序:指針
排序算法的時間複雜度決定了整個計算的時間複雜度。由於雙指針遍歷的複雜度是O(n)。code
在排好序的數組(如下簡稱數組)兩端分別建立left
、right
指針:blog
此時left
值與right
值之和(如下簡稱sum
)大於target
,此時應該將right
左移一位,減少sum
使其更接近target
。排序
從這裏就能夠看出,爲何對有序數組才適用碰撞指針。
在這個case中咱們須要繼續遍歷數組,直到right
指針指向7,此時sum
小於target
:
與步驟2相似,當sum
小於target
時咱們須要右移左指針,增長sum
值使得二者更加接近:
在當前case中,left
指向2時sum
與target
相等,匹配成功!
此時返回left
值和right
值在原數組中的下標便可:
示例代碼以下:
須要注意的是,因爲JavaScript引用類型的特性,咱們首先拷貝了nums
,才使用Array.sort
對拷貝數組進行排序。
另外,對於nums=[1,2,2,3],target=4
這種case,其指望的返回值是[1,2]
而不是[1,1]
或者[2,2]
。因此這裏咱們使用了Array.lastIndexOf()
這個API。
再複習一下暴力運算法和哈希表法:
for
循環暴力運算簡單直觀,時間複雜度O(n2)、空間複雜度O(1);一入JS深似海,但願這個專欄能在你乘風破浪的旅途中有所幫助。歡迎關注個人公衆號:「JS漫步指南」,更多精彩等待您發現!