Logo
Ana Sayfa
ÖZEL KODLAMA DERSLERİ
Yazılım Özel Ders
Tüm birebir programlara genel bakış
Python Yazılım Kursu
Sıfırdan ileri seviyeye birebir Python
Java Yazılım Kursu
OOP odaklı birebir Java eğitimi
AP Computer Science Principles
AP CSP sınav hazırlığı
GRUP DERSLERİ
Python & Django Masterclass
SINIRLI KONTENJAN
Java & Spring Boot Masterclass
SINIRLI KONTENJAN
C# .NET Masterclass
SINIRLI KONTENJAN
VİDEO DERSLER
Sıfırdan Temel Python Kursu
Kendi Hızında Öğren
ÜCRETSİZ
Seviye Testi
Ücretsiz — Python, Java, algoritma seviye testleri
Kariyerini Keşfet
Sertifika Doğrula
Belge numarası ve soyad ile doğrulama

İki İşaretçi (Two Pointer) Tekniği: Mantığı, Kullanım Alanları ve Python/Java Örnekleri

Yazar: Berk Keskin 28.08.2026 ~12 dk okuma 1 Okunma
two-pointer-algoritma-teknigi

Two pointer (iki işaretçi) algoritma tekniği, bir dizi veya liste üzerinde iki farklı indeksi aynı anda ama farklı stratejilerle hareket ettirerek problemi tek bir geçişte çözme yöntemidir. Ne zaman kullanılır sorusunun kısa cevabı şudur: veri sıralıysa, bir çift eleman aranıyorsa, palindrom kontrolü yapılıyorsa ya da bir alt dizi/pencere üzerinde toplam veya uzunluk hesaplanıyorsa two pointer tekniği neredeyse her zaman iç içe döngülerden daha hızlı bir çözüm sunar. Mülakat sorularının büyük bir kısmı aslında bu kalıba oturur; farkı görebilmek ise pratikle gelen bir refleks meselesidir.

Two Pointer Tekniği Nedir? Temel Zihinsel Model

Two pointer tekniğini anlamanın en kolay yolu bir kitabı iki kişinin aynı anda okuduğunu hayal etmektir: biri baştan başlar, diğeri sondan; ikisi ortada buluşana kadar sayfa sayfa ilerlerler ve her adımda birbirlerine göre konumlarını değerlendirirler. İşte two pointer da tam olarak budur — bir dizi üzerinde iki ayrı konumu (indeksi) takip eden ve bu konumları probleme göre birbirine yaklaştıran ya da birlikte kaydıran bir yaklaşımdır. Burada kullanılan "işaretçi" (pointer) kelimesi C/C++'taki bellek adresi anlamına gelmez; sadece dizideki bir elemanın sırasını, yani indeksini işaret eden basit bir sayaçtır. Python veya Java'da bunlar birer tamsayı değişkeninden ibarettir. Pratikte bu iki indeks üç şekilde çalışabilir: biri baştan biri sondan başlayıp ortada buluşana kadar ilerleyebilir, ikisi de baştan başlayıp farklı hızlarda hareket edebilir ya da bir pencerenin başını ve sonunu temsil edebilirler. Hangi varyasyonun seçileceği, problemin doğasına bağlıdır ve bu konuya birazdan daha ayrıntılı değinilecektir.

Bu tekniğe neden ihtiyaç duyduğumuzu bir cümleyle özetlemek gerekirse: aynı sonucu elde etmek için diziyi defalarca baştan taramak yerine, iki işaretçiyi akıllıca yönlendirerek tek geçişte aynı bilgiye ulaşabildiğimiz için two pointer, klasik iç içe döngü yaklaşımına göre ciddi bir performans kazancı sağlar. Bu kazancın nereden geldiğini ve nasıl ölçüldüğünü ise bir sonraki bölümde ayrıntılı olarak ele alacağız.

Brute-Force'a Karşı Two Pointer: Zaman Karmaşıklığı Avantajı

Sıralı bir dizide toplamı belirli bir hedefe eşit olan iki eleman bulmak istediğinizi düşünün. En saf yaklaşım (brute-force), her elemanı dizideki diğer tüm elemanlarla tek tek karşılaştırmaktır: dışarıda bir döngü, onun içinde bir döngü daha çalıştırırsınız. Bu iç içe döngü (nested loop) yapısı, dizideki eleman sayısı arttıkça işlem sayısının kareye katlanarak büyümesine yol açar; bu yüzden bu yaklaşım O(n²) olarak adlandırılır.

Burada geçen Big-O gösterimini hatırlamakta fayda var: Big-O, bir algoritmanın belirli bir donanımda kaç saniye süreceğini değil, girdi büyüklüğü arttıkça yapılan işlem sayısının nasıl bir hızla arttığını ölçen kavramsal bir yöntemdir. Yani O(n²) demek "10 elemanlık dizi şu kadar saniye sürer" demek değil, "eleman sayısı iki katına çıktığında işlem sayısı yaklaşık dört katına çıkar" demektir. Mülakatlarda sorulan "bu çözümün karmaşıklığı nedir" sorusu da tam olarak bu büyüme eğilimini sorar.

Two pointer tekniği aynı problemi tek bir geçişte (single pass) çözer: dizi zaten sıralı olduğu için, iki işaretçiyi mantıklı bir kurala göre hareket ettirerek her adımda arama uzayını daraltabilirsiniz. Bir işaretçiyi ileri, diğerini geri kaydırdığınızda, brute-force'un tekrar tekrar kontrol ettiği pek çok kombinasyonu hiç denemeden elersiniz; çünkü sıralı yapı sayesinde bir sonraki adımda hangi yönde ilerlemeniz gerektiğini önceden bilirsiniz. Bu sayede toplam işlem sayısı, dizinin karesiyle değil doğrudan uzunluğuyla orantılı büyür — yani O(n) seviyesine iner. Bu farkın pratikte ne kadar büyük bir avantaj yarattığını görmek ve kendi algoritma sezginizi test etmek isterseniz, ücretsiz algoritma bilgi testi bu noktada nerede durduğunuzu görmeniz için iyi bir başlangıç noktası olabilir.

Two Pointer'ı Ne Zaman Kullanmalısın? Karar Çerçevesi

Two Pointer'ı Ne Zaman Kullanmalısın? Karar Çerçevesi

Bir problemle karşılaştığınızda two pointer tekniğinin uygun olup olmadığını anlamak için birkaç basit ipucuna bakmak yeterlidir. Dizi veya liste sıralı mı? Problem, toplamı ya da farkı belirli bir koşulu sağlayan bir "çift" eleman bulmayı mı istiyor? Bir metnin ya da dizinin baştan ve sondan aynı okunup okunmadığını, yani palindrom olup olmadığını mı kontrol ediyorsunuz? Yoksa belirli bir uzunlukta ya da toplamda bir alt dizi/pencere (subarray/window) mi arıyorsunuz? Bu sorulardan birine "evet" diyorsanız, iç içe döngü yazmadan önce two pointer'ı denemek mantıklıdır.

Bu ipuçlarını her yeni soruda tek tek gözden geçirmek, zamanla otomatik hale gelen bir kontrol listesi gibi çalışır ve mülakat sırasında panik yapmadan doğru tekniği seçmenizi kolaylaştırır. Bu tür örüntü tanıma alışkanlığını farklı problem tipleri üzerinden geliştirmek isteyenler, algoritma ve veri yapıları üzerine yazılan diğer teknik içerikleri inceleyerek benzer karar çerçevelerini başka konularda da görebilir.

Problem Örüntüsü Uygun Two Pointer Varyasyonu Örnek Problem
Sıralı dizide çift bulma Zıt yönlü işaretçiler (baştan ve sondan) Toplamı hedef değere eşit iki eleman bulma
Palindrom kontrolü Zıt yönlü işaretçiler (ortada buluşana kadar) Bir dizginin veya dizinin simetrik olup olmadığını kontrol etme
Linked list döngü tespiti Fast-slow (tavşan-kaplumbağa) işaretçiler Bağlı listede döngü olup olmadığını bulma
Alt dizi/pencere toplamı Kayan pencere (aynı yönlü iki işaretçi) Belirli toplama ulaşan en kısa/en uzun alt diziyi bulma

Two Pointer Varyasyonları: Fast-Slow ve Zıt Yönlü İşaretçiler

Two pointer tekniği tek bir kalıptan ibaret değildir; problemin yapısına göre işaretçilerin nereden başlayıp hangi yönde hareket edeceği değişir. Bu farklılıklar zamanla iki ana varyasyona ayrılmıştır ve mülakat sorularının büyük kısmı bu iki kalıptan birine oturur.

İlk varyasyon fast-slow pointer (hızlı-yavaş işaretçi) olarak adlandırılır. Bu yaklaşımda iki işaretçi de aynı noktadan, genellikle dizinin veya bağlı listenin (linked list) başından yola çıkar, ancak farklı hızlarda ilerler: yavaş işaretçi her adımda bir eleman ilerlerken hızlı işaretçi iki eleman atlar. Bu kalıp özellikle linked list yapılarında döngü tespiti için klasik bir çözümdür — eğer yapıda bir döngü varsa hızlı işaretçi er ya da geç yavaş işaretçiye yetişir. Aynı mantık, sıralı olmayan bir dizide tekrarlanan eleman bulma veya bir dizinin ortasını tek geçişte belirleme gibi problemlerde de işe yarar.

İkinci varyasyon ise zıt yönlü işaretçiler (opposite ends) yaklaşımıdır. Burada işaretçiler dizinin iki ucundan, biri en baştan biri en sondan başlar ve birbirine doğru ilerler. Bu kalıp, elemanlar arasında bir sıralama ilişkisi olduğunda gerçek gücünü gösterir: sıralı bir dizide hedef toplamı veren iki elemanı bulma, bir string'in palindrom olup olmadığını kontrol etme veya bir kabın en fazla su tutabileceği alanı hesaplama gibi problemler bu grubun tipik örnekleridir. İşaretçiler ortada buluştuğunda ya da birbirini geçtiğinde arama sona erer.

İki varyasyon arasındaki temel farkı tek cümleyle özetlemek gerekirse: fast-slow işaretçiler aynı noktadan başlayıp aynı yönde farklı hızlarla ilerlerken, zıt yönlü işaretçiler farklı uçlardan başlayıp birbirine doğru hareket eder. Hangi problemle karşılaştığınızda hangi kalıbı seçeceğinizi anlamak, kod yazmaya başlamadan önce doğru zihinsel modeli kurmanızı sağlar. Bir sonraki bölümde bu iki kalıptan zıt yönlü işaretçi varyasyonunu somut bir problem üzerinden ele alacağız.

Örnek Problem: Sıralı Dizide Hedef Toplamı Veren İki Eleman

Örnek Problem: Sıralı Dizide Hedef Toplamı Veren İki Eleman

Teoriyi somutlaştırmak için mülakatlarda sıkça karşılaşılan klasik bir soruyu ele alalım: elimizde sıralı (küçükten büyüğe dizilmiş) bir tam sayı dizisi ve bir hedef sayı var; bu dizide toplamları hedef sayıya eşit olan iki elemanın indekslerini bulmamız isteniyor. Örneğin dizi [2, 7, 11, 15] ve hedef değer 9 ise, aranan çift 2 ve 7'dir çünkü toplamları hedefe eşittir.

Bu problem zıt yönlü işaretçi tekniği için neredeyse ders kitabı niteliğinde bir örnektir, çünkü dizinin sıralı olması işaretçilerin hangi yöne kayacağına dair kesin bir karar mekanizması sağlar. Eğer o an baktığınız iki elemanın toplamı hedeften büyükse, dizinin sıralı olması sayesinde en büyük elemanı küçültmeniz gerektiğini kesin olarak bilirsiniz; toplam hedeften küçükse tam tersi geçerlidir. Bu belirlilik, olası her ikili kombinasyonu denemeden, sadece bir geçişte doğru cevaba ulaşmanızı sağlar. Sıralama olmasaydı bu karar mantığı çökerdi, çünkü bir işaretçiyi kaydırmanın toplamı artıracağını mı azaltacağını mı bilemezdiniz.

Bu problemin çözümünü iki farklı dilde, aynı algoritmik mantığı koruyarak inceleyeceğiz. Bir sonraki bölümde Python ile adım adım bir çözüm yazacak, ardından aynı yaklaşımı Java'da nasıl uygulayacağımızı göreceğiz. Amaç, dil farklı olsa da two pointer mantığının değişmediğini somut biçimde görmenizdir.

Python ile Adım Adım Çözüm

Sıralı dizide hedef toplam problemini çözerken izlenecek adımları netleştirmek, kodu yazmadan önce doğru zihinsel modeli kurmanıza yardımcı olur:

  1. Sol işaretçiyi (left) dizinin ilk elemanına, sağ işaretçiyi (right) dizinin son elemanına yerleştirin.
  2. İki işaretçinin gösterdiği elemanların toplamını hesaplayın.
  3. Toplam hedeften büyükse, toplamı küçültmek için sağ işaretçiyi bir adım sola kaydırın.
  4. Toplam hedeften küçükse, toplamı büyütmek için sol işaretçiyi bir adım sağa kaydırın.
  5. Toplam hedefe eşitse, işlemi sonlandırıp iki işaretçinin indekslerini döndürün.
  6. Sol işaretçi sağ işaretçiyi geçene kadar 2-5 arasındaki adımları tekrarlayın.

Bu mantığı Python'da bir while döngüsüyle şu şekilde ifade edebiliriz:

def two_sum_sorted(numbers, target):
    left, right = 0, len(numbers) - 1

    while left < right:
        current_sum = numbers[left] + numbers[right]

        if current_sum == target:
            return [left, right]
        elif current_sum > target:
            right -= 1
        else:
            left += 1

    return None

print(two_sum_sorted([2, 7, 11, 15], 9))  # [0, 1]

Fonksiyonun başındaki left, right = 0, len(numbers) - 1 satırı listedeki 1. adıma karşılık gelir; işaretçileri dizinin iki ucuna yerleştirir. while döngüsü içindeki if-elif-else bloğu ise 3. ve 4. adımlardaki karar mekanizmasını uygular: toplam büyükse right azaltılır, küçükse left artırılır. Döngü, left değeri right'ı geçtiğinde ya da eşit sonuç bulunduğunda sona erer. Bu tarz problemleri kendi başınıza kurup hata ayıklaya ayıklaya çözmek, tekniği gerçek anlamda içselleştirmenin en etkili yoludur; bu süreçte birebir geri bildirim almak isteyenler için birebir Python dersleri bu tür algoritma pratiklerini adım adım pekiştirecek bir ortam sunar.

Java ile Aynı Mantığın Uygulanışı

Python tarafında yazdığın çözümün arkasındaki mantık, Java'ya geçtiğinde birebir aynı kalır; değişen tek şey söz dizimidir (syntax — bir dilin kod yazma kuralları). Sol ve sağ işaretçi kavramı, koşul kontrolü ve işaretçileri kaydırma sırası tamamen aynıdır. Java'da ekstra olarak değişken tiplerini açıkça belirtmen (int[], int) ve süslü parantezlerle blokları kapatman gerekir, ama algoritmanın iskeleti değişmez.

Dizi indeksleme konusunda Java da Python gibi sıfırdan başlar, bu yüzden sağ işaretçiyi nums.length - 1 ile başlatman yeterli. Döngü koşulu da aynı kalır: left değeri right'tan küçük olduğu sürece döngü devam eder. Tek fark, Python'da bir demet (tuple) döndürebilirken Java'da genellikle bir int[] dizisi döndürmen gerekmesidir, çünkü Java'da fonksiyonlar birden fazla değeri doğrudan demet olarak geri veremez.

public class TwoPointerExample {
    public static int[] twoSumSorted(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;

        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == target) {
                return new int[]{left, right};
            } else if (sum < target) {
                left++;
            } else {
                right--;
            }
        }
        return new int[]{-1, -1};
    }

    public static void main(String[] args) {
        int[] nums = {2, 7, 11, 15};
        int[] result = twoSumSorted(nums, 9);
        System.out.println(result[0] + ", " + result[1]);
    }
}

Yukarıdaki kodu çalıştırdığında Python versiyonuyla tamamen aynı adımları izlediğini göreceksin: toplam hedeften küçükse sol işaretçi ilerler, büyükse sağ işaretçi geri çekilir. Bu benzerliği görmek, algoritmik düşünmenin dilden bağımsız olduğunu anlamak açısından değerlidir — mülakatlarda hangi dille sorulursa sorulsun aynı zihinsel modeli uygulayabilirsin. Java söz dizimine ve nesne yönelimli yapılara daha sistemli çalışmak isteyenler için birebir Java özel dersleri bu tür algoritma problemlerini adım adım pekiştirme imkânı sunar.

Tekniğin Sınırları: Sıralı Olmayan Diziler ve Alternatifler

Two pointer tekniğinin çalışma mantığı, dizinin sıralı olmasına dayanır; sol ve sağ işaretçinin hangi yöne hareket edeceğine karar verebilmen için elemanların belirli bir düzende olması gerekir. Dizi sıralı değilse, tekniği doğrudan uygulayamazsın ve önce bir sıralama (sort) işlemi yapman gerekir. Ancak bu sıralama bedavaya gelmez: genel amaçlı sıralama algoritmaları ortalama O(n log n) zaman alır, bu da bazı durumlarda tekniğin kazandırdığı avantajı kısmen götürebilir.

Daha da önemlisi, sıralama işlemi elemanların orijinal sırasını (ve dolayısıyla orijinal indekslerini) bozar. Eğer problem sana "hangi iki elemanın toplamı hedefe eşit" değil de "bu iki elemanın orijinal dizideki indeksleri ne" diye soruyorsa, diziyi sıralayıp two pointer uygulamak seni yanlış cevaba götürür; çünkü sıralama sonrası indeksler artık orijinal konumları göstermez.

Bu tür durumlarda devreye hash set veya hash map tabanlı bir yaklaşım girer. Hash map, her elemanı anahtar-değer çifti olarak sakladığından dizide tek bir geçiş yaparken hem elemanı hem de orijinal indeksini hatırlayabilirsin; bu da sıralama yapmadan O(n) zamanda çözüme ulaşmanı sağlar. Kabaca şu ayrımı yapabilirsin:

  • Dizi zaten sıralıysa veya sıralama maliyeti kabul edilebilirse ve ekstra bellek kullanmak istemiyorsan: sıralama + two pointer tercih edilir.
  • Orijinal indeksler önemliyse veya sıralama maliyetinden tamamen kaçınmak istiyorsan: hash set/hash map tabanlı yaklaşım daha uygundur.

Bu iki yaklaşım arasındaki farkı gerçek problemler üzerinde görmeden sadece okuyarak içselleştirmek zordur. Öğrendiğin bu mantığı pratik sorularla test etmek istersen ücretsiz kodlama bilgisi testi ile hangi yaklaşımı ne zaman seçeceğine dair sezgini ölçebilirsin.

Sık Sorulan Sorular

Two pointer tekniği hangi veri yapılarında kullanılır?

Teknik en çok diziler (array) ve stringler üzerinde kullanılır, çünkü bu yapılarda elemanlara indeks üzerinden doğrudan erişebilirsin. Bağlı listelerde (linked list) de özellikle fast-slow pointer varyasyonuyla sıkça karşılaşılır; ancak hash map veya ağaç gibi indeksli erişimi olmayan yapılarda doğrudan uygulanmaz.

Two pointer ile sliding window (kayan pencere) tekniği aynı şey midir?

Hayır, ikisi akraba tekniklerdir ama aynı değildir. Two pointer'da iki işaretçi genellikle birbirine yaklaşır veya farklı hızlarda ilerler; sliding window'da ise genellikle sabit veya değişken genişlikte bir "pencere" aralığı dizide kaydırılır ve pencere içindeki toplam, ortalama gibi bir değer takip edilir. Sliding window aslında two pointer'ın belirli bir aralığı takip etmeye odaklanan özel bir uygulamasıdır.

Dizi sıralı değilse two pointer tekniği hiç kullanılamaz mı?

Tamamen imkânsız değildir ama doğrudan uygulanamaz. Önce diziyi sıralayıp ardından two pointer uygulayabilirsin; ancak bu, orijinal indeksleri koruman gereken problemlerde işe yaramaz ve ekstra sıralama maliyeti getirir. Bu gibi durumlarda hash set veya hash map tabanlı bir çözüm genellikle daha pratik olur.

Two pointer tekniğinin zaman karmaşıklığı her zaman O(n) mıdır?

Dizi zaten sıralıysa evet, çünkü her iki işaretçi de dizide toplam en fazla n adım ilerler. Ancak dizi sıralı değilse ve önce sıralama yapman gerekiyorsa, toplam zaman karmaşıklığı sıralamanın maliyetiyle birlikte O(n log n) seviyesine çıkar.

Mülakatlarda bir sorunun two pointer ile çözülebileceğini nasıl anlarım?

Soru sıralı bir dizi veya string üzerinde çalışıyorsa, bir çift eleman arasında bir ilişki (toplam, fark, palindrom kontrolü gibi) aranıyorsa ve brute-force çözümün iç içe döngülerle O(n²) çalıştığını fark ediyorsan, bu güçlü bir two pointer sinyalidir. Ayrıca "sıralı dizi" ifadesi soru metninde açıkça geçiyorsa bu neredeyse doğrudan bir ipucudur.

Fast-slow pointer tekniği hangi tür problemlerde tercih edilir?

Fast-slow pointer, özellikle bağlı listelerde döngü tespiti, listenin orta elemanını bulma veya listenin sonundan belirli bir mesafedeki elemanı yakalama gibi problemlerde tercih edilir. İki işaretçinin farklı hızlarda ilerlemesi, dizinin veya listenin tamamını baştan sona taramadan yapısal bilgi elde etmeni sağlar.

Two pointer tekniği, doğru senaryoda kullanıldığında hem kod okunabilirliğini artırır hem de mülakat sürecinde algoritmik düşünme becerini net biçimde ortaya koyar. Bu tür teknikleri Python ve Java üzerinde uygulamalı olarak pekiştirmek istersen online yazılım video eğitimleri ile kendi hızında ilerleyebilirsin.

Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 300'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara