web-dev-qa-db-fra.com

Comment trouver le nième élément à partir de la fin d'une liste chaînée?

La fonction suivante tente de trouver l'élément nth to last d'une liste à liens simples.

Par exemple: 

Si les éléments sont 8->10->5->7->2->1->5->4->10->10, le résultat est 7th jusqu'au dernier nœud est 7.

Quelqu'un peut-il m'aider sur le fonctionnement de ce code ou existe-t-il une approche plus simple et meilleure?

LinkedListNode nthToLast(LinkedListNode head, int n) {
  if (head == null || n < 1) {
    return null;
  }

  LinkedListNode p1 = head;
  LinkedListNode p2 = head;

  for (int j = 0; j < n - 1; ++j) { // skip n-1 steps ahead
    if (p2 == null) {
      return null; // not found since list size < n
    }
    p2 = p2.next;
  }

  while (p2.next != null) {
    p1 = p1.next;
    p2 = p2.next;
  }

  return p1;
}
59
Jony

Votre algorithme fonctionne en créant d’abord des références à deux nœuds de votre liste liée qui sont séparés par N nœuds. Ainsi, dans votre exemple, si N est 7, il définira p1 à 8 et p2 à 4.

Il fera ensuite avancer chaque référence de noeud au prochain noeud de la liste jusqu'à ce que p2 atteigne le dernier élément de la liste. Encore une fois, dans votre exemple, ce sera lorsque p1 est 5 et p2 est 10. À ce stade, p1 fait référence au Nième jusqu'au dernier élément de la liste (par la propriété qu'ils sont séparés de N nœuds).

34
Eric

La clé de cet algorithme consiste à définir deux pointeurs p1 et p2 séparés par les nœuds n-1. Nous voulons donc que p2 pointe vers le nœud (n-1)th à partir du début de la liste, puis nous déplaçons p2 jusqu'à atteindre le nœud last de la liste. Une fois que p2 aura atteint la fin de la liste, p1 pointera vers le nième nœud à partir de la fin de la liste.

J'ai mis l'explication en ligne sous forme de commentaires. J'espère que ça aide:

// Function to return the nth node from the end of a linked list.
// Takes the head pointer to the list and n as input
// Returns the nth node from the end if one exists else returns NULL.
LinkedListNode nthToLast(LinkedListNode head, int n) {
  // If list does not exist or if there are no elements in the list,return NULL
  if (head == null || n < 1) {
    return null;
  }

  // make pointers p1 and p2 point to the start of the list.
  LinkedListNode p1 = head;
  LinkedListNode p2 = head;

  // The key to this algorithm is to set p1 and p2 apart by n-1 nodes initially
  // so we want p2 to point to the (n-1)th node from the start of the list
  // then we move p2 till it reaches the last node of the list. 
  // Once p2 reaches end of the list p1 will be pointing to the nth node 
  // from the end of the list.

  // loop to move p2.
  for (int j = 0; j < n - 1; ++j) { 
   // while moving p2 check if it becomes NULL, that is if it reaches the end
   // of the list. That would mean the list has less than n nodes, so its not 
   // possible to find nth from last, so return NULL.
   if (p2 == null) {
       return null; 
   }
   // move p2 forward.
   p2 = p2.next;
  }

  // at this point p2 is (n-1) nodes ahead of p1. Now keep moving both forward
  // till p2 reaches the last node in the list.
  while (p2.next != null) {
    p1 = p1.next;
    p2 = p2.next;
  }

   // at this point p2 has reached the last node in the list and p1 will be
   // pointing to the nth node from the last..so return it.
   return p1;
 }

Alternativement, nous pouvons définir p1 et p2 séparés par n nœuds au lieu de (n-1), puis déplacer p2 jusqu'à la fin de la liste au lieu de passer au dernier nœud:

LinkedListNode p1 = head;
LinkedListNode p2 = head;
for (int j = 0; j < n ; ++j) { // make then n nodes apart.
    if (p2 == null) {
        return null;
    }
    p2 = p2.next;
}
while (p2 != null) { // move till p2 goes past the end of the list.
    p1 = p1.next;
    p2 = p2.next;
}
return p1;
62
codaddict

Que pensez-vous de cette approche?.

  1. Compter la longueur de la liste chaînée.
  2. Index de nœud réel de tête = longueur de la liste chaînée - index donné;
  3. Ecrivez une fonction dans travesre de head et obtenez le nœud à l’index ci-dessus.
9
Pritam Karmakar
//this  is the recursive solution


//initial call
find(HEAD,k);

// main function
void find(struct link *temp,int k)
{  
 if( temp->next != NULL)
   find( temp->next, k);
 if((c++) == k)       // c is initially declared as 1 and k is the node to find from last.
  cout<<temp->num<<' ';
}
7
dekontj

Il y a déjà beaucoup de réponses ici, mais ils parcourent tous la liste deux fois (de manière séquentielle ou parallèle) ou utilisent beaucoup d'espace de stockage supplémentaire.

Vous pouvez le faire en parcourant la liste une seule fois (plus un peu) en utilisant un espace supplémentaire constant:

Node *getNthFromEnd(Node *list, int n) {

    if (list == null || n<1) {
        return null; //no such element
    }

    Node *mark1 = list, *mark2 = list, *markend = list;
    int pos1 = 0, pos2 = 0, posend = 0;

    while (markend!=null) {
        if ((posend-pos2)>=(n-1)) {
            mark1=mark2;
            pos1=pos2;
            mark2=markend;
            pos2=posend;
        }
        markend=markend->next;
        ++posend;
    }
    if (posend<n) {
        return null; //not enough elements in the list
    }

    //mark1 and mark2 are n-1 elements apart, and the end is at least
    //1 element after mark2, so mark1 is at least n elements from the end

    while((posend - pos1) > n) {
      mark1 = mark1->next;
      ++pos1;
    }
    return mark1;
}

Cette version utilise 2 pointeurs supplémentaires qui font moins que N+n traversals, où N est la longueur de la liste et n est l'argument.

Si vous utilisez des pointeurs M extra, vous pouvez le réduire à N+ceil(n/(M-1)) (et vous devez les stocker dans un tampon circulaire).

3
Matt Timmermans

Comme cela ressemble à des devoirs, je préfère vous aider à vous aider vous-même plutôt que de donner une solution réelle.

Je vous suggère d'exécuter ce code sur un petit échantillon de données. Utilisez votre débogueur pour exécuter des lignes pas à pas (vous pouvez définir un point d'arrêt au début de la fonction). Cela devrait vous donner une idée du fonctionnement du code.

Vous pouvez également Console.WriteLine() pour afficher les variables d’intérêt.

2
mafu

Juste une autre solution à ce problème. Bien que la complexité temporelle reste la même, ce code réalise la solution en une seule boucle.

public Link findKthElementFromEnd(MyLinkedList linkedList, int k)
    {
        Link current = linkedList.getFirst();//current node
        Link currentK = linkedList.getFirst();//node at index k

        int counter = 0;

        while(current.getNext()!=null)
        {
            counter++;

            if(counter>=k)
            {
                currentK = currentK.getNext();
            }

            current = current.getNext();
        }

        //reached end
        return currentK;
    }
2
sunsin1985

Vous pouvez simplement parcourir la liste liée et obtenir la taille. Une fois que vous avez la taille, vous pouvez trouver le deuxième terme dans 2n qui est encore O(n). 

public T nthToLast(int n) {
    // return null if linkedlist is empty
    if (head == null) return null;

    // declare placeholder where size of linkedlist will be stored
    // we are hoping that size of linkedlist is less than MAX of INT
    int size = 0;

    // This is O(n) for sure
    Node i = head;
    while (i.next != null) {
        size += 1;
        i = i.next;
    }

    // if user chose something outside the size of the linkedlist return null
    if (size < n)
        return null;

    // This is O(n) if n == size
    i = head;
    while(size > n) {
        size--;
        i = i.next;
    }

    // Time complexity = n + n = 2n
    // therefore O(n)

    return i.value;
}
2
Y_Y

Solution en C #. Créez une LinkedList avec des valeurs factices.

  LinkedList<int> ll = new LinkedList<int>();
            ll.AddFirst(10);
            ll.AddLast(12);
            ll.AddLast(2);
            ll.AddLast(8);
            ll.AddLast(9);
            ll.AddLast(22);
            ll.AddLast(17);
            ll.AddLast(19);
            ll.AddLast(20);

Créez 2 pointeurs p1 et p1 qui pointent vers le premier nœud.

        private static bool ReturnKthElement(LinkedList<int> ll, int k)
        {
            LinkedListNode<int> p1 = ll.First;
            LinkedListNode<int> p2 = ll.First;

Parcourez la boucle jusqu'à ce que p2 soit nul - ce qui signifie que la longueur de la liste chaînée est inférieure à Kth élément OR jusqu'à l'élément Kth

            for (int i = 0; i < k; i++)
            {
                p2 = p2.Next;
                if (p2 == null)
                {
                    Console.WriteLine($"Linkedlist is smaller than {k}th Element");
                    return false;
                }
            }

Maintenant, itérez les deux pointeurs jusqu'à ce que p2 soit nul. La valeur contenue dans le pointeur p1 correspondra à Kth Element


            while (p2 != null)
            {
                p1 = p1.Next;
                p2 = p2.Next;
            }
            //p1 is the Kth Element
            Console.WriteLine($"Kth element is {p1.Value}");
            return true;
        }
2
VAT

Inversez simplement la liste chaînée en temps linéaire et trouvez le kième élément. Il fonctionne toujours en temps linéaire.

2
Nithin
public int nthFromLast(int n){
    Node current = head;
    Node reference = head;      
    for(int i=0;i<n;i++){
        reference=reference.getNext();
    }
    while(reference != null){
        current = current.getNext();
        reference = reference.getNext();
    }
    return current.getData();
}
1
kaila88

Utilisez deux pointeurs pTemp et NthNode. Initialement, les deux points sont dirigés vers le noeud principal de la liste. NthNode commence à se déplacer uniquement après que pTemp ait effectué n déplacements. Les deux avancent jusqu'à ce que pTemp atteigne la fin de la liste. En conséquence, NthNode pointe sur le nième nœud à partir de la fin de la liste liée.

public ListNode NthNodeFromEnd(int n){
    ListNode pTemp = head, NthNode = null;
   for(int count=1; count<n;count++){
     if(pTemp!=null){
       pTemp = pTemp.getNext();
     }
   }
   while(pTemp!=null){
     if(NthNode==null){
         NthNode = head;
     }
     else{
        NthNode = NthNode.getNext();
     }
     pTemp = pTemp.getNext();
   }
   if(NthNode!=null){
     NthNode = NthNode.getNext();
     return NthNode;
   }
return null;
}

Référence TextBook: "Structure de données et algorithmes simplifiés en Java"

1
Balasubramanian

Pour comprendre ce problème, nous devrions faire une simple analogie avec un exemple de mesure. Disons que vous devez trouver la position de votre bras à exactement 1 mètre de votre majeur, comment mesureriez-vous? Il vous suffirait de saisir une règle de 1 mètre de long et de placer l'extrémité supérieure de cette règle au bout de votre majeur, l'extrémité inférieure du mètre se trouvant à exactement 1 mètre du haut de votre milieu. doigt.

Ce que nous faisons dans cet exemple sera le même, nous avons juste besoin d’un cadre avec un élément n large et nous devons placer le cadre à la fin de la liste, ainsi le nœud de départ du cadre sera exactement n- e élément à la fin de la liste.

Ceci est notre liste en supposant que nous avons M éléments dans la liste et notre cadre avec N élément large;

HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)

<-- Frame -->

Cependant, nous n'avons besoin que des limites de la trame, ainsi la limite de fin de la trame sera exactement (N-1) éléments à l'écart de la limite de début de la trame. Donc, ne devez stocker que ces éléments de frontière. Appelons-les A et B;

HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)

A <- N-Element Wide-> B

La première chose à faire est de trouver B, qui est la fin du cadre. 

ListNode<T> b = head;
int count = 1;

while(count < n && b != null) {
    b = b.next;
    count++;
}

Maintenant, b est le n-ième élément du tableau et a est situé sur la tête . Pour que notre cadre soit défini, nous allons incrémenter les deux nœuds limites étape par étape jusqu'à ce que b atteigne la fin de la liste, où a sera le n-ème avant-dernier élément;

ListNode<T> a = head;

while(b.next != null) {
    a = a.next;
    b = b.next;
}

return a;

Pour tout rassembler, et avec les contrôles HEAD, N <M (où M est la taille de la liste) et autres, voici la méthode de la solution complète;

public ListNode<T> findNthToLast(int n) {
    if(head == null) {
        return null;
    } else {
        ListNode<T> b = head;
        int count = 1;

        while(count < n && b != null) {
            b = b.next;
            count++;
        }

        if(count == n && b!=null) {
            ListNode<T> a = head;

            while(b.next != null) {
                a = a.next;
                b = b.next;
            }

            return a;
        } else {
            System.out.print("N(" + n + ") must be equal or smaller then the size of the list");
            return null;
        }
    }
}
1
Levent Divilioglu

J'ai ma solution récursive à un autre thread dans StackOverflow ici

1
sanjay

Non, vous ne connaissez pas la longueur de la liste de liens .... Vous devrez parcourir une fois pour obtenir la longueur de la liste des éléments préférés, votre approche est donc peu efficace;

1
CodeR

Nous prenons ici deux pointeurs pNode et qNode, les deux points initiaux étant dirigés vers la tête qNode. Ensuite, parcourez jusqu'à la fin de la liste et le pNode ne traversera que lorsqu'il existe une différence entre le nombre et la position est supérieure à 0 et que pthNode s'incrémente une fois dans chaque boucle.

static ListNode nthNode(int pos){
ListNode pNode=head;
ListNode qNode=head;
int count =0;
while(qNode!=null){
    count++;
    if(count - pos > 0)
        pNode=pNode.next;
    qNode=qNode.next;
}
return pNode;
}
1
Rohit

Le problème posé dans le livre de la coupe est légèrement différent. Il est dit de trouver le dernier élément d’une liste à liens simples.

Voici mon code:

    public void findntolast(int index)
    {
        Node ptr = front; int count = 0;
        while(ptr!=null)
        {
            count++;
            if (count == index)
            {
                front = ptr;
                break;
            }
            ptr = ptr.next;
        }
        Node temp=front;
        while(temp!=null)
        {
            Console.WriteLine(temp.data);
            temp=temp.next;
        }
    }
0
Akshay

Solution récursive:

Node findKth (Node head, int count, int k) {
    if(head == null)
        return head;
    else {
        Node n =findKth(head.next,count,k);
        count++;

        if(count == k)
            return head;

        return n;
    }
}
0
Maher Rezeq

mon approche, ce que je pense est simple et a une complexité temporelle O (n).

Étape 1: commencez par obtenir le nombre de nœuds. Exécuter une boucle for à partir du premier nœud jusqu'au dernier nœud

Étape 2: Une fois que vous avez le compte, appliquez un calcul simple, par exemple, si nous avons trouvé le 7ème noeud du dernier noeud et que le nombre de tous les noeuds est égal à 12, alors (count - index) - 1 donnera un kème noeud, jusqu'à lequel vous devrez traverser et ce sera le nième nœud au dernier nœud. Dans ce cas (12 -7) -1 = 4

Si les éléments sont 8-> 10-> 5-> 7-> 2-> 1-> 5-> 4-> 10-> 10 alors le résultat est le 7ème et dernier noeud est 7, ce qui n'est rien d'autre que le 4ème noeud de le début.

0
Dhananjaya HS

pouvez-vous utiliser une structure de données supplémentaire .. si c'est simple ... commencez à placer tous les nœuds dans une pile, maintenez un compteur et affichez-le. selon votre exemple, 8-> 10-> 5-> 7-> 2-> 1-> 5-> 4-> 10-> 10 commencez à lire la liste chaînée et commencez à pousser les nœuds ou le nœud-> données sur une pile. ainsi la pile ressemblera à top -> {10, 10,4, 5, 1, 2, 7, 5, 10, 8} <- bottom.

commencez maintenant à sortir du haut de la pile en maintenant un compteur = 1 et chaque fois que vous sautez augmentez le compteur de 1, lorsque vous atteignez le n-ième élément (dans votre exemple 7ème élément), arrêtez de sauter.

remarque: ceci imprimera ou récupérera les données/nœuds en ordre inverse

0
funnyCoder

Voici le code utilisant l'approche à 2 pointeurs: ( source )

Approche lente et plus rapide du pointeur

struct node
{
  int data;
  struct node *next;
}mynode;


mynode * nthNodeFrmEnd(mynode *head, int n /*pass 0 for last node*/)
{
  mynode *ptr1,*ptr2;
  int count;

  if(!head)
  {
    return(NULL);
  }

  ptr1  = head;
  ptr2  = head;
  count = 0;

  while(count < n)
  {
     count++;
     if((ptr1=ptr1->next)==NULL)
     {
        //Length of the linked list less than n. Error.
        return(NULL);
     }
  }

  while((ptr1=ptr1->next)!=NULL)
  {
    ptr2=ptr2->next;
  }

  return(ptr2);
}


Récursion

node* findNthNode (node* head, int find, int& found){
    if(!head) {
        found = 1;
        return 0;
    }
    node* retval = findNthNode(head->next, find, found);
    if(found==find)
        retval = head;
    found = found + 1;
    return retval;
}

0
kinshuk4

Voici la version C # de la recherche du nième enfant à partir de Linklist.

public Node GetNthLast(Node head, int n)
    {
        Node current, nth;
        current = nth = head;
        int counter = 0;

        while (current.next != null)
        {
            counter++;
            if (counter % n == 0)
            {
                for (var i = 0; i < n - 1; i++)
                {
                    nth = nth.next;
                }
            }
            current = current.next;
        }
        var remainingCounts = counter % n;
        for (var i = 0; i < remainingCounts; i++)
        {
            nth = nth.next;
        }
        return nth;
    }
0
Shafqat Ali

Vous pouvez également résoudre le problème ci-dessus à l'aide de tables de hachage.Les entrées de la table de hachage sont la position du nœud et l'adresse du nœud. Donc, si nous voulons trouver le nième nœud à partir de la fin (cela signifie m-n + 1 à partir du premier où m est le nombre de nœuds). Maintenant, lorsque nous entrons dans la table de hachage, nous obtenons le nombre de nœuds.

1. Traversez chaque noeud et faites les entrées correspondantes dans la table de hachage.

2.Look pour le nœud m-n + 1 dans la table de hachage, nous obtenons l'adresse.

La complexité temporelle est O (n).

0
Shiv Shakti

En fonction de la tolérance au coût de la mémoire (O (k) dans cette solution), nous pourrions allouer un tableau de pointeurs de longueur k et le renseigner avec les nœuds sous forme de tableau circulaire tout en parcourant la liste liée. 

Lorsque nous aurons fini de parcourir la liste liée, le premier élément du tableau (assurez-vous simplement de calculer l'indice 0 correctement car il s'agit d'un tableau circulaire), nous aurons la réponse.

Si le premier élément du tableau est null, il n'y a pas de solution à notre problème.

0
Ignacio Hagopian

Je pense qu'il y a une faille dans le code de la question, et je me demande si elle a été extraite d'un livre. Comment est-ce possible? Il peut s'exécuter correctement, mais le code est quelque peu logiquement incorrect. Dans la boucle for ... la condition if doit être vérifiée par rapport à p2->next ! = NULL

 for (int j = 0; j < n - 1; ++j) { // skip n-1 steps ahead
       if (p2->next == null) {
       return null; // not found since list size < n
   }

... le reste est correct et les explications étant donné que le code change déjà p2(n-1) positions d'avance sur p1, puis dans la boucle, il les déplace simultanément jusqu'à ce que p2->next atteigne la fin.

0
user1107108

Tout d'abord

Comme mentionné dans le commentaire, mais pour être plus clair, la question est de

<Cracking the coding interview 6th> | IX Interview Questions | 2. Linked Lists | Question 2.2.

C'est un excellent livre de Gayle Laakmann McDowell, un ingénieur en logiciels de Google, qui a interviewé beaucoup de gens.


Approches

(En supposant que la liste chaînée ne garde pas la trace de la longueur), il existe deux approches dans O(n) time et O(1) espace:

  • Recherchez d'abord la longueur, puis passez en boucle à l'élément (len-k + 1).
    Cette solution n'est pas mentionnée dans le livre, si je me souviens bien.
  • Boucle, via 2 pointeur, gardez-les à distance (k-1).
    Cette solution est tirée du livre, comme dans la question.

Code

Voici l’implémentation dans Java, avec le test unitaire, (sans utiliser de structure de données avancée dans JDK lui-même).

KthToEnd.Java

/**
 * Find k-th element to end of singly linked list, whose size unknown,
 * <p>1-th is the last, 2-th is the one before last,
 *
 * @author eric
 * @date 1/21/19 4:41 PM
 */
public class KthToEnd {
    /**
     * Find the k-th to end element, by find length first.
     *
     * @param head
     * @param k
     * @return
     */
    public static Integer kthToEndViaLen(LinkedListNode<Integer> head, int k) {
        int len = head.getCount(); // find length,

        if (len < k) return null; // not enough element,

        return (Integer) head.getKth(len - k).value; // get target element with its position calculated,
    }

    /**
     * Find the k-th to end element, via 2 pinter that has (k-1) distance.
     *
     * @param head
     * @param k
     * @return
     */
    public static Integer kthToEndVia2Pointer(LinkedListNode<Integer> head, int k) {
        LinkedListNode<Integer> p0 = head; // begin at 0-th element,
        LinkedListNode<Integer> p1 = head.getKth(k - 1); // begin at (k-1)-th element,

        while (p1.next != null) {
            p0 = p0.next;
            p1 = p1.next;
        }

        return p0.value;
    }

    static class LinkedListNode<T> {
        private T value;
        private LinkedListNode next;

        public LinkedListNode(T value) {
            this.value = value;
        }

        /**
         * Append a new node to end.
         *
         * @param value
         * @return new node
         */
        public LinkedListNode append(T value) {
            LinkedListNode end = getEnd();
            end.next = new LinkedListNode(value);
            return end.next;
        }

        /**
         * Append a range of number, range [start, end).
         *
         * @param start included,
         * @param end   excluded,
         */
        public void appendRangeNum(Integer start, Integer end) {
            KthToEnd.LinkedListNode last = getEnd();
            for (int i = start; i < end; i++) {
                last = last.append(i);
            }
        }

        /**
         * Get end element of the linked list this node belongs to, time complexity: O(n).
         *
         * @return
         */
        public LinkedListNode getEnd() {
            LinkedListNode end = this;
            while (end != null && end.next != null) {
                end = end.next;
            }

            return end;
        }

        /**
         * Count of element, with this as head of linked list.
         *
         * @return
         */
        public int getCount() {
            LinkedListNode end = this;
            int count = 0;
            while (end != null) {
                count++;
                end = end.next;
            }

            return count;
        }

        /**
         * Get k-th element from beginning, k start from 0.
         *
         * @param k
         * @return
         */
        public LinkedListNode getKth(int k) {
            LinkedListNode<T> target = this;
            while (k-- > 0) {
                target = target.next;
            }

            return target;
        }
    }
}

KthToEndTest.Java

(test unitaire, en utilisant TestNG, ou vous passez à JUnit/.., comme vous le souhaitez)

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

/**
 * KthToEnd test.
 *
 * @author eric
 * @date 1/21/19 5:20 PM
 */
public class KthToEndTest {
    private int len = 10;
    private KthToEnd.LinkedListNode<Integer> head;

    @BeforeClass
    public void prepare() {
        // prepare linked list with value [0, len-1],
        head = new KthToEnd.LinkedListNode(0);
        head.appendRangeNum(1, len);
    }

    @Test
    public void testKthToEndViaLen() {
        // validate
        for (int i = 1; i <= len; i++) {
            Assert.assertEquals(KthToEnd.kthToEndViaLen(head, i).intValue(), len - i);
        }
    }

    @Test
    public void testKthToEndVia2Pointer() {
        // validate
        for (int i = 1; i <= len; i++) {
            Assert.assertEquals(KthToEnd.kthToEndVia2Pointer(head, i).intValue(), len - i);
        }
    }
}

Conseils:

  • KthToEnd.LinkedListNode
    C’est un simple nœud de liste à lien unique, implémenté à partir de zéro, il représente une liste liée à partir de lui-même.
    Il ne suit pas non plus la tête/la queue/la longueur, bien qu'il dispose de méthodes pour le faire.
0
Eric Wang

En Java, je vais utiliser 

public class LL {
  Node head;
  int linksCount;

   LL(){
     head = new Node();
     linksCount = 0;
   }

  //TRAVERSE TO INDEX
  public Node getNodeAt(int index){
    Node temp= head;
    if(index > linksCount){
        System.out.println("index out of bound !");
        return null;
    }
    for(int i=0;i<index && (temp.getNext() != null);i++){
        temp = temp.getNext();
    }
    return temp.getNext();
  }
}
0
Manisha

Personne ici n'a remarqué que la version de Jonathan lève une exception NullPinterException si le n est supérieur à la longueur de LinkedList . Voici ma version:

public Node nth(int n){
        if(head == null || n < 1) return null;

        Node n1 = head;
        Node n2 = head;
        for(int i = 1; i < n; i++){
            if(n1.next == null) return null; 
            n1 = n1.next;
        }

        while (n1.next != null){
            n1 = n1.next;
            n2 = n2.next;
        }
        return n2;
}

Je ne fais que peu de changement ici: lorsque le nœud n1 avance, au lieu de vérifier si n1 est nul, je vérifie que le temps n1.next est nul ou sinon, la boucle while n1.next lève une exception NullPinterException.

0
sofia