所謂雙指標,指的是在遍歷物件的過程中,不是普通的使用單個指標進行訪問,而是使用兩個相同方向或者相反方向的指標進行掃瞄,從而達到相應的目的。
換言之,雙指標法充分使用了陣列有序這一特徵,從而在某些情況下能夠簡化一些運算。
(注:這裡的指標,並非專指c中指標的概念,而是指索引,游標或指標,可迭代物件等)
這類演算法包括:
1.給定乙個有序遞增陣列,在陣列中找到滿足條件的兩個數,使得這兩個數的和為某一給定的值。如果有多對數,只輸出一對即可。
對於這種問題,常見的演算法思路不外乎遍歷,回溯,但這裡,雙指標遍曆法是乙個很有效的方法。具體思路是:初始化兩個指標,乙個指向陣列的第乙個元素,另外乙個指向陣列的最後乙個元素,在兩個指標相遇之前,指標1只能向前移動,指標2 只能向後移動。比較當前兩個指標所指元素和與給定數字的大小,如果和較大,指標2向後移動,如果和較小,指標1向前移動。最終的結果是找到兩個滿足條件的數或者不存在這樣的兩個數字。
如圖所示:
據此思路,不難寫出**:
[cpp]view plain
copy
print?
#include
intgetthepair(
int*a,
intn,
intthenum,
int&left,
int&right)
if(sum
if(sum > thenum)
} return
0;
} int
main();
intstart = 0,end = 0;
for(
inti = 1; i <= 16; i++)else
} return
0;
}
2.雙指標應用之二:hoare的雙向掃瞄快速劃分法。快速排序的總結中已經給了思路和**,為了方便,這裡再次給出**:
[cpp]view plain
copy
print?
inthoare_partition(
intarr,
intstart,
intend)
else
return
j;
} }
3.雙指標應用之三。
奇偶排序。忘記是哪個公司的面試題了。題目大意是這樣的,給定乙個陣列,陣列中元素有奇數有偶數。要求對陣列進行處理,使得陣列的左邊為奇數,右邊為偶數
這個題目直接看上去,跟快速排序的劃分十分類似,唯一不同的是,不需要返回索引。所以,簡單的方式如下:
[cpp]view plain
copy
print?
void
partition(
int*arr,
intn)
} }
4.雙指標法的應用之四:求單鏈表的中間元素。
這個大家應該都比較熟悉了。對於單鏈表求中間元素的問題,經典的作法是採用兩個指標,初始化都指向煉表表頭,移動開始時,快指標移動兩步,慢指標移動一步。當快指標的next為null或者快指標為null的時候,慢指標所指的就是單鏈表的中間元素(注意奇數個元素和偶數個元素的處理)
[cpp]view plain
copy
print?
/** 取單鏈表的中間元素,如果單鏈表元素為奇數個,那麼去中間的元素,如果是偶數個,取後面的乙個元素。
*/linklist getmidelem(const
linklist l)
linklist first = l;
linklist second = l;
while
(first != null && first->next != null)
return
second;
}
完整的**可見:
當然,雙指標法還有其他一些應用等待你的發現,它是一種奇妙的思維方式,不是麼?
雙指標法的常見應用
標籤 演算法 pivot null面試 2012 08 10 10 09 3247人閱讀收藏 舉報 資料結構 演算法 20 所謂雙指標,指的是在遍歷物件的過程中,不是普通的使用單個指標進行訪問,而是使用兩個相同方向或者相反方向的指標進行掃瞄,從而達到相應的目的。換言之,雙指標法充分使用了陣列有序這一...
雙指標法LeetCode總結
遍歷物件的過程中,使用兩個指標進行操作,實現相應的目的 經典環形鍊錶 leetcode142 待補充適用於有序陣列,設定陣列左索引與陣列右索引 基本流程是 publicf int nums leetcode11 盛水最多的容器 class solution return max leetcode15...
演算法思維 雙指標法
雙指標可分為三類 其中,滑動視窗 已單獨寫了一篇隨筆,可跳轉檢視。在快慢指標中,又有一類典型演算法,叫 floyd s cycle finding algorithm,其又名floyd s hare and tortoise algorithm。在這裡,我們主要談論左右指標和快慢指標。左右指標 主要...