Coding Interview Prep · Pelajaran

Pengodean String, Pembalikan, dan Palindrome

Implementasikan pembalikan kata secara in-place, pengodean run-length, dan deteksi palindrome, termasuk teknik memperluas dari bagian tengah.

Pelajaran 4 dari 413 langkah

Pengodean String, Pembalikan, dan Palindrome adalah pelajaran Coding Interview Prep gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Coding Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Membalik Teks di Tempat

Teks Python tidak dapat diubah, jadi pembalikan ‘di tempat’ berarti mengonversinya menjadi daftar karakter, menukarnya dengan dua penunjuk, lalu menggabungkannya. Pertukaran klasik dengan dua penunjuk: tempatkan left pada indeks 0 dan right pada indeks terakhir; tukarkan karakter dan gerakkan penunjuk ke arah dalam hingga keduanya berpapasan. Ini memerlukan waktu O(n) dan ruang O(n) untuk daftar karakter (tidak dapat dihindari karena teks tidak dapat diubah).

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'

Membalik Kata dalam Kalimat

Balik urutan kata sambil merapikan spasi berlebih. Solusi Python yang rapi: gunakan split (menangani beberapa spasi), balikkan daftar, lalu gunakan join. Untuk pembalikan di tempat pada larik karakter: balikkan seluruh larik, lalu balikkan setiap kata secara terpisah. Pendekatan dua lintasan ini berjalan dalam waktu O(n) dengan ruang O(n) (tidak terhindarkan pada teks Python karena teks tidak dapat diubah).

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]))

Deteksi Palindrom: Sederhana

Sebuah teks adalah palindrom jika sama dengan kebalikannya. Pemeriksaan Python tercepat: s == s[::-1]. Untuk palindrom yang hanya berisi karakter alfanumerik tanpa membedakan huruf besar-kecil (varian wawancara yang paling umum), normalkan teks terlebih dahulu: saring karakter nonalfanumerik dan ubah menjadi huruf kecil, lalu bandingkan. Kedua pendekatan memerlukan waktu O(n).

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

Deteksi Palindrom: Dua Penunjuk

Untuk menggunakan ruang tambahan O(1), periksa palindrom dengan dua penunjuk, bukan dengan pemotongan. Tempatkan left pada 0 dan right di akhir. Lewati karakter nonalfanumerik, bandingkan karakter yang tersisa tanpa membedakan huruf besar-kecil, lalu kembalikan False jika tidak cocok. Pendekatan ini memang lebih panjang, tetapi sepenuhnya menghindari pembuatan teks bersih — hal yang penting ketika memori terbatas.

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

Ekspansi dari Pusat untuk Menemukan Palindrom Terpanjang

Teknik ekspansi dari pusat menemukan substring palindrom terpanjang dalam waktu O(n²) dengan ruang tambahan O(1). Untuk setiap karakter (palindrom berpanjang ganjil) dan setiap celah di antara karakter (palindrom berpanjang genap), lakukan ekspansi ke luar selama karakter-karakternya cocok. Catat pasangan (awal, akhir) terbaik yang ditemukan. Ada 2n-1 pusat, dan setiap ekspansi memerlukan O(n) pada kasus terburuk.

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'

Pratinjau Algoritme Manacher

Algoritme Manacher menemukan substring palindrom terpanjang dalam waktu O(n), dengan memanfaatkan wawasan bahwa palindrom di dalam palindrom yang lebih besar dapat diinisialisasi dari posisi cerminnya. Algoritme ini jarang diminta untuk diimplementasikan dalam wawancara, tetapi tetap layak diketahui. Sebagian besar pewawancara menerima pendekatan ekspansi dari pusat O(n²) sebagai ‘cukup optimal’ — sebutkan Manacher sebagai solusi teoretis O(n) jika diminta menindaklanjutinya.

# 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'

Pengodean Panjang Runtun

Pengodean panjang runtun (RLE) memampatkan karakter berulang yang berurutan: 'aaabbc' menjadi 'a3b2c1'. Implementasinya: lakukan pemindaian dengan penunjuk cepat untuk menemukan akhir setiap runtun, tulis karakter dan jumlahnya ke dalam daftar keluaran, lalu gunakan join. Masukan mungkin lebih pendek daripada keluaran berkode untuk runtun pendek — selalu periksa apakah versi berkode lebih pendek sebelum mengembalikannya.

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)

Mendekode Teks Berkode Panjang Runtun

Pendekodean RLE membaca karakter dan rangkaian digit setelahnya, lalu mengembangkan setiap runtun. Pewawancara terkadang menyajikan varian LeetCode yang menggunakan k[encoded_string] untuk mengulang substring: misalnya, 3[ab] → ababab. Varian bertingkat ini memerlukan tumpukan untuk menangani beberapa tingkat penyarangan.

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'

Palindrom Valid II: Boleh Menghapus Satu Karakter

Diberikan sebuah teks, kembalikan True jika Anda dapat menjadikannya palindrom dengan menghapus paling banyak satu karakter. Gunakan dua penunjuk; saat menemukan ketidakcocokan pertama, periksa apakah s[left+1:right+1] atau s[left:right] merupakan palindrom (yaitu, coba lewati masing-masing karakter yang tidak cocok). Jika salah satunya merupakan palindrom, kembalikan True. Pendekatan rakus ini berhasil karena melewati karakter yang tidak cocok merupakan satu-satunya tindakan yang berguna.

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

Partisi Palindrom I

Partisikan teks menjadi semua bagian teks yang merupakan palindrom. Gunakan penelusuran mundur: pada setiap langkah, coba semua prefiks dari teks yang tersisa; jika suatu prefiks merupakan palindrom, lanjutkan secara rekursif pada bagian sisanya. Prakomputasikan tabel logika 2D is_pal[i][j] menggunakan DP interval agar pemeriksaan palindrom memerlukan O(1), sehingga penelusuran mundur keseluruhan berkurang dari O(n² × 2^n) menjadi O(n × 2^n) — dapat diterima karena menghasilkan semua partisi memang bersifat eksponensial.

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']]

Palindrom Terpendek: Penghashan Teks

Temukan palindrom terpendek yang dapat diperoleh dengan menambahkan karakter ke bagian depan teks. Wawasan utamanya adalah menemukan prefiks palindrom terpanjang dari s, lalu menambahkan kebalikan sufiks yang tersisa ke bagian depan. Untuk menemukan prefiks palindrom terpanjang secara efisien, gunakan fungsi kegagalan KMP pada teks s + '#' + reverse(s). Nilai terakhir fungsi kegagalan memberikan panjang prefiks palindrom terpanjang.

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'

Cek Singkat

Uji pemahaman Anda tentang konsep Struktur Data & Algoritma — Persiapan Wawancara Pemrograman dari pelajaran ini.

Rangkuman Pelajaran

Dalam pelajaran ini Anda mempelajari: deteksi palindrom dengan dua penunjuk memerlukan waktu O(n) dan ruang O(1) — selalu utamakan pemeriksaan berbasis indeks daripada mengalokasikan salinan terbalik jika ruang menjadi pertimbangan, ekspansi dari pusat menemukan substring palindrom terpanjang dalam O(n²) dengan menjadikan setiap dari 2n-1 posisi sebagai pusat palindrom potensial, dan pengodean panjang runtun memampatkan runtun berurutan dalam O(n), sedangkan pendekodean memerlukan tumpukan untuk varian kurung bertingkat. Selanjutnya kita akan membahas pengurutan gelembung dan pengurutan penyisipan.

Gratis untuk memulai

Belajar Coding Interview Prep dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
90
Pelajaran
360

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pengodean String, Pembalikan, dan Palindrome” gratis?

Ya — teks lengkap “Pengodean String, Pembalikan, dan Palindrome” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Coding Interview Prep, upgrade ke CoddyKit PRO. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pengodean String, Pembalikan, dan Palindrome”?

Implementasikan pembalikan kata secara in-place, pengodean run-length, dan deteksi palindrome, termasuk teknik memperluas dari bagian tengah. Kamu berlatih Coding Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Coding Interview Prep?

Tidak diperlukan pengalaman sebelumnya. Coding Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Pengodean String, Pembalikan, dan Palindrome” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Coding Interview Prep ini?

Ya. Setiap pelajaran Coding Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. API String Python untuk Wawancara
  2. Sliding Window untuk Substring
  3. Anagram dan Peta Frekuensi Karakter
  4. Pengodean String, Pembalikan, dan Palindrome
← Kembali ke Coding Interview Prep