0Pricing
DSA Interview Prep · Leçon

Bases des tableaux et opérations en place

Revoyez l’indexation et la mutation, ainsi que les pièges les plus courants des entretiens sur les tableaux, comme les erreurs de décalage d’une position et la modification d’une liste pendant son parcours.

Bases des tableaux et opérations en place est une leçon DSA Interview Prep gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage DSA Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours DSA Interview Prep comprend 4 leçons au total.

Les tableaux comme mémoire contiguë

En interne, une liste Python repose sur un tableau dynamique — un bloc de mémoire contigu où les éléments sont stockés à des adresses consécutives. Cette disposition permet un accès aléatoire en O(1) par indice : Python calcule instantanément address = base + index × element_size. Les insertions ou suppressions au milieu nécessitent de décaler tous les éléments suivants, ce qui coûte O(n). Cette asymétrie est à l’origine de la plupart des discussions sur les compromis liés aux tableaux en entretien.

nums = [10, 20, 30, 40, 50]
# O(1) random access
print(nums[2])       # 30
print(nums[-1])      # 50

# O(1) append (amortised)
nums.append(60)
print(nums)          # [10,20,30,40,50,60]

# O(n) insert at beginning
nums.insert(0, 0)    # shifts all elements right
print(nums)          # [0,10,20,30,40,50,60]

Décalage d’une unité : le bug classique des tableaux

Les erreurs de décalage d’une unité sont la source la plus fréquente de mauvaises réponses dans les problèmes de tableaux. L’indexation à partir de 0 de Python signifie que le dernier indice valide est len(arr) - 1. Lorsque vous écrivez des boucles, déterminez si vous avez besoin de < ou de <= en vérifiant la condition aux limites avec la plus petite entrée valide (n=1 ou n=2). Vérifiez toujours vos limites avec des exemples concrets avant de valider votre réponse.

def find_max(nums):
    # Use len(nums)-1 as last index
    max_val = nums[0]              # safe if n >= 1
    for i in range(1, len(nums)):  # start at 1, not 0
        if nums[i] > max_val:
            max_val = nums[i]
    return max_val

print(find_max([3, 1, 4, 1, 5]))  # 5
print(find_max([7]))               # 7  (single element)
# Would crash if we accessed nums[len(nums)]

Inversion en place avec deux pointeurs

Inverser un tableau en place consiste à utiliser deux pointeurs partant des extrémités opposées et à les échanger en progressant vers le centre jusqu’à leur rencontre. Cela nécessite un espace supplémentaire en O(1) et un temps en O(n). La condition left < right (strictement inférieur) garantit la correction pour les longueurs paires comme impaires : avec un nombre impair d’éléments, l’élément central reste automatiquement à sa place.

def reverse_inplace(arr):
    left, right = 0, len(arr) - 1
    while left < right:
        arr[left], arr[right] = arr[right], arr[left]
        left  += 1
        right -= 1
    # Space: O(1)  Time: O(n)

a = [1, 2, 3, 4, 5]
reverse_inplace(a)
print(a)  # [5, 4, 3, 2, 1]

b = [1, 2, 3]
reverse_inplace(b)
print(b)  # [3, 2, 1]  middle element unchanged

Rotation d’un tableau en place

Faire pivoter un tableau vers la droite de k positions peut se faire en place en inversant trois segments : inversez tout le tableau, puis les k premiers éléments, puis les n-k éléments restants. Cette méthode atteint un temps en O(n) et un espace en O(1), ce qui est bien meilleur que l’approche en O(n) spatial qui consiste à découper puis concaténer. Réduisez toujours k modulo n pour gérer le cas k ≥ n.

def rotate(nums, k):
    n = len(nums)
    k %= n  # handle k >= n

    def rev(l, r):
        while l < r:
            nums[l], nums[r] = nums[r], nums[l]
            l += 1; r -= 1

    rev(0, n-1)    # reverse all
    rev(0, k-1)    # reverse first k
    rev(k, n-1)    # reverse rest

a = [1, 2, 3, 4, 5, 6, 7]
rotate(a, 3)
print(a)  # [5, 6, 7, 1, 2, 3, 4]

Suppression d’éléments en place

Supprimer les doublons ou les valeurs cibles en place utilise un pointeur d’écriture qui indique où doit être écrit le prochain élément valide. Le pointeur de lecture parcourt le tableau vers l’avant ; lorsqu’il trouve un élément valide, il le copie à la position d’écriture, puis avance les deux pointeurs. C’est le motif central de problèmes LeetCode comme « supprimer un élément », « supprimer les doublons d’un tableau trié » et « déplacer les zéros ».

def remove_element(nums, val):
    write = 0
    for read in range(len(nums)):
        if nums[read] != val:
            nums[write] = nums[read]
            write += 1
    return write  # new length

nums = [3, 2, 2, 3]
new_len = remove_element(nums, 3)
print(nums[:new_len])  # [2, 2]

nums2 = [0, 1, 2, 2, 3, 0, 4, 2]
new_len2 = remove_element(nums2, 2)
print(nums2[:new_len2])  # [0, 1, 3, 0, 4]

Déplacer les zéros : pointeur de lecture-écriture

Déplacez tous les zéros à la fin d’un tableau tout en préservant l’ordre des éléments non nuls. L’approche du pointeur de lecture-écriture place chaque élément non nul à la position d’écriture, puis remplit la fin avec des zéros. Une autre approche échange les zéros vers l’arrière, en préservant l’ordre sans seconde passe de remplissage. Les deux approches s’exécutent en O(n) et utilisent O(1) espace supplémentaire.

def move_zeroes(nums):
    write = 0
    # Move all non-zeroes to front
    for read in range(len(nums)):
        if nums[read] != 0:
            nums[write] = nums[read]
            write += 1
    # Fill rest with zeroes
    while write < len(nums):
        nums[write] = 0
        write += 1

a = [0, 1, 0, 3, 12]
move_zeroes(a)
print(a)  # [1, 3, 12, 0, 0]

Mettre au carré et trier en place

Étant donné un tableau trié d’entiers, éventuellement négatifs, renvoyez un tableau contenant leurs carrés dans l’ordre croissant. L’approche naïve consiste à calculer les carrés, puis à trier le résultat : O(n log n). L’approche optimale à deux pointeurs exploite le fait que les plus grands carrés proviennent de l’une ou l’autre extrémité du tableau d’entrée trié : comparez les valeurs absolues des éléments les plus à gauche et les plus à droite, puis remplissez le résultat de droite à gauche en O(n).

def sorted_squares(nums):
    n = len(nums)
    result = [0] * n
    left, right = 0, n - 1
    pos = n - 1  # fill from the right
    while left <= right:
        l_sq = nums[left]  ** 2
        r_sq = nums[right] ** 2
        if l_sq > r_sq:
            result[pos] = l_sq
            left += 1
        else:
            result[pos] = r_sq
            right -= 1
        pos -= 1
    return result

print(sorted_squares([-4, -1, 0, 3, 10]))
# [0, 1, 9, 16, 100]

Trouver le pivot et partitionner

Le problème du drapeau national néerlandais partitionne un tableau en trois sections (inférieure au pivot, égale au pivot, supérieure au pivot) en place à l’aide de trois pointeurs. Il s’agit de l’étape clé du tri rapide et de la solution LeetCode « sort couleurs ». Le maintien de l’invariant selon lequel les éléments situés avant le pointeur bas sont < pivot et ceux situés après le pointeur haut sont > pivot guide l’algorithme.

def sort_colors(nums):
    # Dutch national flag: 0s, 1s, 2s
    low, mid, high = 0, 0, len(nums) - 1
    while mid <= high:
        if nums[mid] == 0:
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1; mid += 1
        elif nums[mid] == 1:
            mid += 1
        else:
            nums[mid], nums[high] = nums[high], nums[mid]
            high -= 1  # don't advance mid: new nums[mid] unexamined

a = [2, 0, 2, 1, 1, 0]
sort_colors(a)
print(a)  # [0, 0, 1, 1, 2, 2]

Modifier les éléments d’un tableau pendant une itération

Vous pouvez sans risque modifier les valeurs des éléments (par exemple, les multiplier par -1 pour marquer les éléments déjà visités) pendant une itération, mais ne modifiez jamais la longueur d’une liste pendant une boucle for. Une astuce d’encodage sûre consiste à coder temporairement deux valeurs dans un seul entier (par exemple, à l’aide du bit de signe) afin de simuler un booléen supplémentaire par élément sans allouer d’espace supplémentaire. Cette technique apparaît dans des problèmes comme « trouver tous les nombres absents d’un tableau ».

def find_disappeared(nums):
    # Mark visited by negating the value at the index
    for n in nums:
        idx = abs(n) - 1
        if nums[idx] > 0:
            nums[idx] *= -1  # mark as seen
    # Indices with positive values are missing
    return [i + 1 for i, v in enumerate(nums) if v > 0]

print(find_disappeared([4, 3, 2, 7, 8, 2, 3, 1]))
# [5, 6]  -- O(n) time, O(1) extra space

Liste de contrôle des méthodes pour les tableaux

Avant de programmer une solution à un problème de tableau, parcourez cette liste de contrôle mentale :

  • Le tableau est-il trié ? (cela permet d’utiliser deux pointeurs ou une recherche binaire)
  • Les éléments sont-ils bornés (par exemple, de 1 à n) ? (cela permet des astuces fondées sur les indices)
  • Le traitement en place est-il requis ? (pointeur de lecture-écriture ou échanges)
  • Ai-je besoin de toutes les paires ou d’une seule ? (cela détermine si des boucles imbriquées sont acceptables)
  • Cas limites : tableau vide, élément unique, valeurs toutes identiques
Répondre à ces questions avant d’écrire le code réduit considérablement le temps consacré au débogage.

def max_profit(prices):
    # Pattern: single scan, track running minimum
    # Time: O(n), Space: O(1)
    if not prices: return 0  # edge case: empty
    min_price = prices[0]
    max_prof  = 0
    for price in prices[1:]:  # start at index 1
        max_prof  = max(max_prof, price - min_price)
        min_price = min(min_price, price)
    return max_prof

print(max_profit([7, 1, 5, 3, 6, 4]))  # 5
print(max_profit([7, 6, 4, 3, 1]))     # 0

Algorithme de Kadane : sous-tableau de somme maximale

L’algorithme de Kadane trouve le sous-tableau contigu de somme maximale en O(n) et avec un espace O(1). À chaque étape, déterminez s’il faut prolonger le sous-tableau actuel ou en commencer un nouveau : current = max(num, current + num). Si current + num est inférieur à num seul, le sous-tableau actuel nous pénalise et nous repartons de zéro. Suivez le maximum global tout au long du parcours.

def max_subarray(nums):
    current = global_max = nums[0]
    for n in nums[1:]:
        current    = max(n, current + n)  # extend or restart
        global_max = max(global_max, current)
    return global_max

print(max_subarray([-2, 1, -3, 4, -1, 2, 1, -5, 4]))
# 6  (subarray [4, -1, 2, 1])
print(max_subarray([-1, -2, -3]))
# -1  (all negative: take the least negative)

Vérification rapide

Vérifiez votre compréhension des concepts de structures de données et d’algorithmes — préparation aux entretiens de programmation — présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que les tableaux offrent un accès aléatoire en O(1), mais que les insertions et suppressions au milieu coûtent O(n) — connaître cette asymétrie guide le choix de l’algorithme, que le schéma du pointeur de lecture-écriture supprime des éléments ou déplace des valeurs en place en O(n) avec un espace O(1), et que le codage à l’aide du bit de signe et les astuces utilisant l’indice comme marqueur permettent des solutions en espace O(1) à des problèmes qui nécessiteraient autrement un tableau auxiliaire. Nous allons maintenant étudier les sommes préfixes et les totaux cumulés.

Questions Fréquemment Posées

La leçon « Bases des tableaux et opérations en place » est-elle gratuite ?

Oui — le texte complet de « Bases des tableaux et opérations en place » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours DSA Interview Prep, passe à CoddyKit PRO. Le cours DSA Interview Prep comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Bases des tableaux et opérations en place » ?

Revoyez l’indexation et la mutation, ainsi que les pièges les plus courants des entretiens sur les tableaux, comme les erreurs de décalage d’une position et la modification d’une liste pendant son pa… Tu pratiques DSA Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer DSA Interview Prep ?

Aucune expérience préalable n'est requise. DSA Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Bases des tableaux et opérations en place » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon DSA Interview Prep ?

Oui. Chaque leçon DSA Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Bases des tableaux et opérations en place
  2. Sommes préfixes et totaux cumulés
  3. Deux pointeurs : extrémités opposées
  4. Deux pointeurs : lent et rapide
← Retour à DSA Interview Prep