Aller au contenu

Plus petit ancêtre commun

🧓 Cet exercice utilise une modélisation d'arbre non ordonné, avec la liste des parents.

Ancêtres d'un nœud

On définit les ancêtres d'un nœud \(N\) comme l'ensemble des nœuds rencontrés depuis le nœud \(N\) jusqu'à la racine en allant successivement de parent en parent.

  • Un nœud est ancêtre de lui-même.
  • La racine est un ancêtre de tout nœud de l'arbre.
  • Les ancêtres d'un nœud \(N\) sont ordonnés du plus petit (le nœud \(N\)), au plus grand (la racine).

Plus petit ancêtre commun à deux nœuds

Deux nœuds \(N_1\) et \(N_2\) étant donnés, on considère l'ensemble des ancêtres communs à \(N_1\) et \(N_2\). Cet ensemble est non vide ; la racine étant un ancêtre commun. Cet ensemble est totalement ordonné par la relation de parenté. Il existe donc un unique nœud \(N_0\), le plus petit parmi les ancêtres communs à \(N_1\) et \(N_2\), on l'appelle le plus petit ancêtre commun à \(N_1\) et \(N_2\).

Exercice

Coder une fonction telle que plus_petit_ancêtre_commun(parents, noeud_a, noeud_b) renvoie le plus petit ancêtre commun à noeud_a et noeud_b dans l'arbre non ordonné décrit par sa liste des parents.

Exemples

graph TD
    R(6) --> N1(5)
    R    --> N2(12)
    R    --> N3(10)
    N2   --> N4(4)
    N2   --> N5(1)
    N2   --> N6(0)
    N5   --> N7(7)
    N5   --> N8(3)
    N6   --> N9(9)
    N6   --> N10(8)
    N9   --> N11(11)
    N9   --> N12(2)
🐍 Console Python
>>> # Indices   0   1  2  3   4  5    6   7  8  9 10 11 12
>>> parents = [12, 12, 9, 1, 12, 6, None, 1, 0, 0, 6, 9, 6]
>>> plus_petit_ancêtre_commun(parents, 0, 11)
0
>>> plus_petit_ancêtre_commun(parents, 1, 10)
6
>>> plus_petit_ancêtre_commun(parents, 4, 2)
12
Indice
  • On peut construire une pile avec les ancêtres de noeud_a, une autre pile pour ceux de noeud_b. Ceci peut se faire via une fonction auxiliaire qui renvoie tous les ancêtres d'un nœud.
  • Le sommet de chaque pile sera commun : la racine de l'arbre.
  • On peut les dépiler tant que le sommet est identique.
Guide
🐍 Script Python
def plus_petit_ancêtre_commun(parents, noeud_a, noeud_b):
    "Renvoie le ppac de `noeud_a` et `noeud_b` dans l'arbre défini avec `parents`"

    def ancêtres(parents, noeud):
        "Renvoie les ancêtres du `noeud` dans l'arbre défini par `parents`"
        ancêtres_noeud = ...
        [...]
        return ancêtres_noeud


    [...]
    return ppac
###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : /
.128013],59/f.!78rnb N_o=ylaeêpcwgu)vd461`3kRméhtsP(S02[-i:050F0w0Q0v0Z0u0R0o0z0u0v0R0R0s010Q0Z0y010406050R0C0N0N0v0l0t040U0r0u0C0^0r0m050f0 1113150}0y04051l1e1o0f1l0}0F0Z0E0-0/0;0?0P0Z0B0P0u1C0P0Q0{050(0n0u0w1x0:0=011B1D1F1D0Q1L1N1J0Q0l1m0Q0P1P1z010g0*0w0m0v0N0w010-180R0y0v0m0?0W1J1`1|1*1R1-1N1:1=0{0a0o0S0l0r0y0r0R0Z1b0m0o0$1^0l0l0w0z2j1e210m1m0f1(2w1#1%1$1K0F230?1F0m1/2g1J1u1w0.1Q2G0Z2I0m0r2M1J0y2p1m2u2w2!0~1{2k2O1+2T0l120u0{0o0I2t2(0|2%222*1R2,2.2:0W2?1|2^2u2F012}0v2/040o0K312v0}342{0?37390o0G3d332(353j2:0d3n3f3p3h360r2-382:0H3u2_2)1y2|3z2~3a0j3E3g3H3i3J3B3a0k3N3w3P3y3A3k0e3V2`3X3r040I0V3$3G2P3Y3K0I2=1f2@3v3%3/3)0I303@323_3.2+3R390I3c3 3e3F3q440{0I3m483o3`433Z4d3t4g414b4k3*3D4n4a3x3|3M4t3O3{4c3*3U4y3W4A4q0I3#4E4i3I4q0W3,4K424M3K0W3?2!4o4v4B0W3~2$1r2Y1e2M2z0F1%2E3x0z2U1?1m4*1n4(4$2$4:0$2Z4F1+0L0{0$0g3n4u3X0A2:554z2+0g0{0y190R0q0y0%2i0q1|0z0x1#0w0q4:110C1d4g563/0`040T5a4 2|5e131/0Q0R5D4L0?5A0c3n0o5y2+0{2T0w0C0F5m5L4R5N0{5P4g5R5b5F045V5X0q0n5!355A0D0!3u0o5{5*5E0?0R1 04010M1/0E0r0Z1O1N0o0y1{0z2l1O0J5.5Y0v0J0o0%0o6h0r5W5Y0n6l0F1|0,0u00130n2p2l0O1-0m0Z0o0v0E2q6o1{2p0m5J0J013u065|5}5M015104535=3x583a6$3(5d045n5p2p5K5x5+5$5B6*3{5G6O5J6_1+5O5Q5S5,6i6~1R5@5_4n6V6V725 61636567690w0,6.5q0,0F0C6o6i6u6w0o6y6A6C0F6E2R6H6N6M5H6P0R6R5`7a5{7c360{7l6:0q745)7L0r0{0s716?015A0X753i5U6q5X7$7Z0{0b7I7J7L6Z0A1B1N7X5~7M5-7)0F7_6X0r6(0Z6;2!6W5#01817(0Q7 870L0z0{0p1c0w7+5A784W7J7:7Y0m7(6r8c357U047W7S8q6{5I842@7L7!7+8r7|8t6=7`5A7.798o7b8A6-0m5o7m7Q7}7+8w0h8H7N6c1/7~8L6X5A5C8+878I7R2$7Y5@7/7a7;0{2p0Q0C0l5w857L8I7O7j8X8K4W066U5|937N8U6/960v8u3x8w8y928S958D328F0{8.8?7`8I6N8C8k5%9j3(8s5/9i8/5?0{0D8_9d8T8V7P5;8z7`9l9C6`9N9g9q2v9s6^9H4v8B7F9A045(9n9w9E6s9*9K4n9b7K7Y7=7@8j9R8,9t8_8R8M9 9$9D9W8W9G9-800{0i9m2@869I040X0b9=a987898T8*alag9u8E9o9f8W9Qaq9kabad32af3x7!aja09c7Yan1|apae9!as9rau9O9h9*7#a43/8w0Y7+0N0Z4d9*8Oay3X9laB2vaDa59p5:aU8Z0{aZaW1+a#a%a`767-ak3^a19~045^aH9^9.046c0v0z9U1+9T9}8:9eaS5ha8at9S0{8#a~7%ba2e9*0Tb1408Q9Ma;axbnaa04bq9v6X9xbubr7,5Bbx3eb38d8|0%8 91aN8Sbbbd4t0f4|0w2w2Xb%4)1v4+2z2C2x0v1Mb*0f4*0}b@0%0)0+04.