0Pricing
Coding Interview Prep · Ders

Dize Kodlama, Ters Çevirme ve Palindromlar

Yerinde sözcük ters çevirmeyi, çalışma uzunluğu kodlamasını ve merkezden dışa genişletme tekniği de dâhil olmak üzere palindrom denetimini uygulayın.

Dize Kodlama, Ters Çevirme ve Palindromlar, CoddyKit'te ücretsiz bir Coding Interview Prep dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Coding Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Coding Interview Prep kursu toplamda 4 dersten oluşur.

Bir Dizeyi Yerinde Tersine Çevirme

Python dizeleri değişmezdir; bu nedenle "yerinde" tersine çevirme, dizeyi bir karakter listesine dönüştürmek, iki işaretçiyle karakterlerin yerini değiştirmek ve listeyi birleştirmek anlamına gelir. Klasik iki işaretçiyle yer değiştirme yönteminde left değerini 0. dizine, right değerini son dizine yerleştirin; karakterlerin yerini değiştirip işaretçileri birbirlerine doğru ilerletin ve işaretçiler kesişene kadar devam edin. Bu işlem, karakter listesi için O(n) zaman ve O(n) alan kullanır; dizeler değişmez olduğu için bu alan kullanımı azaltılamaz.

def reverse_string(s):
    chars = list(s)
    left, right = 0, len(chars) - 1
    while left < right:
        chars[left], chars[right] = chars[right], chars[left]
        left  += 1
        right -= 1
    return ''.join(chars)

print(reverse_string('hello'))   # 'olleh'
print(reverse_string('Hannah'))  # 'hannaH'

# Pythonic shortcut (creates new string):
print('hello'[::-1])  # 'olleh'

Cümledeki Kelimeleri Tersine Çevirme

Fazladan boşlukları kaldırırken kelimelerin sırasını tersine çevirin. Temiz Python çözümü: split (birden çok boşluğu işler), listeyi reverse, ardından join. Karakter dizisi üzerinde yerinde tersine çevirme için dizinin tamamını tersine çevirin, sonra her bir kelimeyi ayrı ayrı tersine çevirin. Bu iki geçişli yaklaşım, O(n) zamanda ve O(n) alan kullanır; Python dizeleri değişmez olduğu için bu alan kullanımı kaçınılmazdır.

def reverse_words(s):
    words = s.split()       # split and strip whitespace
    words.reverse()         # in-place reverse
    return ' '.join(words)  # single space between words

print(reverse_words('  hello   world  '))  # 'world hello'
print(reverse_words('a good example'))     # 'example good a'

# One-liner:
print(' '.join('  hello   world  '.split()[::-1]))

Palindrom Denetimi: Basit Yöntem

Bir dize, tersine çevrilmiş hâline eşitse palindromdur. Python'daki en hızlı denetim: s == s[::-1]. Büyük/küçük harfe duyarsız, yalnızca alfanümerik karakterlerden oluşan palindromlar için (mülakatlarda en sık kullanılan varyant) önce dizeyi normalleştirin: alfanümerik olmayan karakterleri filtreleyip küçük harfe dönüştürün, ardından karşılaştırın. Her iki yaklaşım da O(n) karmaşıklığındadır.

def is_palindrome(s):
    # Filter and normalise
    cleaned = ''.join(c.lower() for c in s if c.isalnum())
    return cleaned == cleaned[::-1]

print(is_palindrome('A man, a plan, a canal: Panama'))  # True
print(is_palindrome('race a car'))                       # False
print(is_palindrome('Was it a car or a cat I saw?'))     # True

Palindrom Denetimi: İki İşaretçi

O(1) ek alan kullanmak için dilimleme yerine palindromu iki işaretçiyle denetleyin. left değerini 0'a, right değerini sona yerleştirin. Alfanümerik olmayan karakterleri atlayın, kalan karakterleri büyük/küçük harfe duyarsız biçimde karşılaştırın ve uyuşmazlıkta Yanlış döndürün. Bu yöntem daha uzun olsa da temizlenmiş dizenin tamamını oluşturmanızı önler; bellek kısıtlı olduğunda bu önemlidir.

def is_palindrome_twoptr(s):
    left, right = 0, len(s) - 1
    while left < right:
        while left < right and not s[left].isalnum():
            left += 1
        while left < right and not s[right].isalnum():
            right -= 1
        if s[left].lower() != s[right].lower():
            return False
        left += 1; right -= 1
    return True

print(is_palindrome_twoptr('A man, a plan, a canal: Panama'))  # True

En Uzun Palindrom İçin Merkez Etrafında Genişletme

Merkez etrafında genişletme tekniği, en uzun palindromik alt dizeyi O(n²) zamanda ve O(1) ek alanla bulur. Her karakter için (tek uzunluklu palindromlar) ve karakterler arasındaki her boşluk için (çift uzunluklu palindromlar), karakterler eşleştiği sürece dışa doğru expand edin. Görülen en iyi (başlangıç, bitiş) çiftini izleyin. 2n-1 merkez vardır ve her genişletme en kötü durumda O(n) sürer.

def longest_palindrome(s):
    best_start = best_end = 0

    def expand(left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1; right += 1
        return left + 1, right - 1  # last valid bounds

    for i in range(len(s)):
        l, r = expand(i, i)      # odd-length
        if r - l > best_end - best_start:
            best_start, best_end = l, r
        l, r = expand(i, i + 1)  # even-length
        if r - l > best_end - best_start:
            best_start, best_end = l, r

    return s[best_start:best_end+1]

print(longest_palindrome('babad'))    # 'bab' or 'aba'
print(longest_palindrome('cbbd'))     # 'bb'

Manacher Algoritmasına Genel Bakış

Manacher algoritması, daha büyük bir palindromun içindeki palindromun bir ayna konumundan başlatılabileceği gözleminden yararlanarak en uzun palindromik alt dizeyi O(n) zamanda bulur. Mülakatlarda bu algoritmanın uygulanması nadiren istenir, ancak varlığından haberdar olmak faydalıdır. Çoğu mülakatçı, O(n²) karmaşıklığındaki merkez etrafında genişletme yaklaşımını "yeterince iyi bir en iyi çözüm" olarak kabul eder; ek bir soru olarak teorik O(n) çözümü istenirse Manacher algoritmasından söz edin.

# Manacher's: O(n) longest palindromic substring
def manacher(s):
    # Transform s into '#a#b#a#' to handle even/odd uniformly
    t = '#' + '#'.join(s) + '#'
    n = len(t)
    P = [0] * n  # P[i] = palindrome radius at i
    center = right = 0
    for i in range(n):
        mirror = 2 * center - i
        if i < right:
            P[i] = min(right - i, P[mirror])
        while (i + P[i] + 1 < n and i - P[i] - 1 >= 0
               and t[i+P[i]+1] == t[i-P[i]-1]):
            P[i] += 1
        if i + P[i] > right:
            center, right = i, i + P[i]
    max_len = max(P)
    center_idx = P.index(max_len)
    start = (center_idx - max_len) // 2
    return s[start:start+max_len]

print(manacher('babad'))   # 'bab'

Çalışma Uzunluğu Kodlaması

Çalışma uzunluğu kodlaması (RLE), art arda tekrarlanan karakterleri sıkıştırır: 'aaabbc', 'a3b2c1' hâline gelir. Uygulamada her çalışmanın sonunu bulmak için hızlı bir işaretçiyle tarama yapın, karakteri ve sayısını bir çıktı listesine yazın, ardından listeyi join ile birleştirin. Kısa çalışmalar için girdi, kodlanmış çıktıdan daha kısa olabilir; döndürmeden önce kodlanmış sürümün daha kısa olup olmadığını her zaman denetleyin.

def encode_rle(s):
    if not s: return ''
    parts = []
    i = 0
    while i < len(s):
        char = s[i]
        j = i
        while j < len(s) and s[j] == char:
            j += 1
        count = j - i
        parts.append(char + (str(count) if count > 1 else ''))
        i = j
    encoded = ''.join(parts)
    return encoded if len(encoded) < len(s) else s

print(encode_rle('aaabbc'))    # 'a3b2c'
print(encode_rle('abc'))       # 'abc'  (no compression gain)

Çalışma Uzunluğu Kodlanmış Dizelerin Kodunu Çözme

RLE kodunu çözme işlemi, karakterleri ve ardından gelen rakam dizilerini okuyarak her çalışmayı genişletir. Mülakatçılar bazen kodlamanın tekrarlanan alt dizeler için k[encoded_string] biçimini kullandığı LeetCode varyantını sunar; örneğin 3[ab] → ababab. Bu iç içe varyantta birden çok iç içelik düzeyini işlemek için yığın gerekir.

def decode_rle(s):
    result = []
    i = 0
    while i < len(s):
        char = s[i]; i += 1
        num_str = ''
        while i < len(s) and s[i].isdigit():
            num_str += s[i]; i += 1
        count = int(num_str) if num_str else 1
        result.append(char * count)
    return ''.join(result)

print(decode_rle('a3b2c'))    # 'aaabbc'
print(decode_rle('a2b3c1'))   # 'aabbbc'

# Nested bracket decode (LeetCode 394)
def decode_bracket(s):
    stack = []
    for c in s:
        if c != ']':
            stack.append(c)
        else:
            chars = []
            while stack[-1] != '[':
                chars.append(stack.pop())
            stack.pop()  # remove '['
            k = int(stack.pop())
            stack.append(''.join(reversed(chars)) * k)
    return ''.join(stack)
print(decode_bracket('3[ab]'))  # 'ababab'

Geçerli Palindrom II: Bir Silmeye İzin Verilir

Bir dize verildiğinde, en fazla bir karakter silerek onu palindroma dönüştürebiliyorsanız Doğru döndürün. İki işaretçi kullanın; ilk uyuşmazlıkta s[left+1:right+1] veya s[left:right] ifadelerinden birinin palindrom olup olmadığını denetleyin (yani uyuşmayan karakterlerin her birini atlamayı deneyin). Taraflardan biri palindromsa Doğru döndürün. Bu açgözlü yaklaşım işe yarar, çünkü uyuşmayan karakteri atlamak tek yararlı eylemdir.

def valid_palindrome(s):
    def is_pal(l, r):
        while l < r:
            if s[l] != s[r]: return False
            l += 1; r -= 1
        return True

    left, right = 0, len(s) - 1
    while left < right:
        if s[left] != s[right]:
            # Try skipping either character
            return is_pal(left+1, right) or is_pal(left, right-1)
        left += 1; right -= 1
    return True

print(valid_palindrome('aba'))    # True
print(valid_palindrome('abca'))   # True  (delete 'c')
print(valid_palindrome('abc'))    # False

Palindromlara Bölme I

Bir dizeyi palindrom olan tüm alt dizelere bölümlendirin. Geri izleme kullanın: her adımda kalan dizenin tüm ön eklerini deneyin; bir ön ek palindromsa kalan kısım üzerinde özyinelemeli olarak devam edin. Palindrom denetimlerini O(1) yapmak için aralık DP'si kullanarak is_pal[i][j] biçiminde iki boyutlu bir doğru/yanlış tablosunu önceden hesaplayın. Böylece toplam geri izleme karmaşıklığı O(n² × 2^n) yerine O(n × 2^n) olur; tüm bölümlendirmeleri üretmek doğası gereği üstel olduğundan bu kabul edilebilir.

def partition(s):
    n = len(s)
    dp = [[False]*n for _ in range(n)]
    for i in range(n):
        dp[i][i] = True
    for length in range(2, n+1):
        for i in range(n-length+1):
            j = i + length - 1
            if s[i] == s[j]:
                dp[i][j] = length == 2 or dp[i+1][j-1]

    result = []
    def backtrack(start, path):
        if start == n: result.append(path[:]); return
        for end in range(start, n):
            if dp[start][end]:
                path.append(s[start:end+1])
                backtrack(end+1, path)
                path.pop()
    backtrack(0, [])
    return result

print(partition('aab'))  # [['a','a','b'],['aa','b']]

En Kısa Palindrom: Dize Karma İşlemi

Bir dizenin başına karakterler ekleyerek elde edilebilecek en kısa palindromu bulun. Temel fikir şudur: s içindeki en uzun palindromik ön eki bulun, ardından kalan son ekin tersine çevrilmiş hâlini başa ekleyin. En uzun palindromik ön eki verimli biçimde bulmak için s + '#' + reverse(s) dizesi üzerinde KMP'nin başarısızlık işlevini kullanın. Başarısızlık işlevinin son değeri, en uzun palindromik ön ekin uzunluğunu verir.

def shortest_palindrome(s):
    rev = s[::-1]
    combined = s + '#' + rev  # '#' prevents overlap
    n = len(combined)
    kmp = [0] * n
    j = 0
    for i in range(1, n):
        while j > 0 and combined[i] != combined[j]:
            j = kmp[j-1]
        if combined[i] == combined[j]:
            j += 1
        kmp[i] = j
    # kmp[-1] = length of longest palindromic prefix
    to_add = rev[:len(s) - kmp[-1]]
    return to_add + s

print(shortest_palindrome('aacecaaa'))  # 'aaacecaaa'
print(shortest_palindrome('abcd'))      # 'dcbabcd'

Hızlı Kontrol

Bu dersteki Veri Yapıları ve Algoritmalar — Kodlama Mülakatı Hazırlığı kavramlarını ne kadar anladığınızı sınayın.

Ders Özeti

Bu derste şunları öğrendiniz: iki işaretçiyle palindrom denetimi O(n) zaman ve O(1) alan kullanır; alan önemli olduğunda tersine çevrilmiş bir copy oluşturmaktansa her zaman dizin tabanlı denetimleri tercih edin, merkez etrafında genişletme, 2n-1 konumun her birini olası bir palindrom merkezi olarak ele alarak en uzun palindromik alt dizeyi O(n²) zamanda bulur ve çalışma uzunluğu kodlaması art arda gelen çalışmaları O(n) zamanda sıkıştırırken, kodu çözme işlemi iç içe köşeli parantez varyantı için bir yığın gerektirir. Sırada kabarcık sıralaması ve eklemeli sıralamayı inceliyoruz.

Sıkça Sorulan Sorular

“Dize Kodlama, Ters Çevirme ve Palindromlar” dersi ücretsiz mi?

Evet — “Dize Kodlama, Ters Çevirme ve Palindromlar” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Coding Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Coding Interview Prep kursu toplamda 4 dersten oluşur.

“Dize Kodlama, Ters Çevirme ve Palindromlar” dersinde ne öğreneceğim?

Yerinde sözcük ters çevirmeyi, çalışma uzunluğu kodlamasını ve merkezden dışa genişletme tekniği de dâhil olmak üzere palindrom denetimini uygulayın. Coding Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Coding Interview Prep öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Coding Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Dize Kodlama, Ters Çevirme ve Palindromlar” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Coding Interview Prep dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Coding Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Mülakatlar için Python Dize API’si
  2. Alt Dizeler için Kayan Pencere
  3. Anagramlar ve Karakter Sıklığı Haritaları
  4. Dize Kodlama, Ters Çevirme ve Palindromlar
← Coding Interview Prep Sayfasına Dön