Вопрос на собеседовании: удалить дубликаты из несортированного связанного списка

Я читаю Cracking the Coding Интервью, четвертое издание: 150 вопросов и решений для интервью по программированию , и я пытаюсь решить следующий вопрос:

2.1 Напишите код для удаления дубликатов из несортированного связного списка. СЛЕДОВАТЬ UP: Как бы вы решили эту проблему, если бы временный буфер не разрешен?

Я решаю это на C #, поэтому я создал свой собственный класс Node :

public class Node where T : class
{
    public Node Next { get; set; }
    public T Value { get; set; }

    public Node(T value)
    {
        Next = null;
        Value = value;
    }
}

Мое решение - перебрать список, а затем повторить для каждого узла через оставшуюся часть списка и удалите все дубликаты (обратите внимание, что я на самом деле не компилировал и не тестировал это, как указано в книге):

public void RemoveDuplicates(Node head)
{
    // Iterate through the list
    Node iter = head;
    while(iter != null)
    {
        // Iterate to the remaining nodes in the list
        Node current = iter;
        while(current!= null && current.Next != null)
        {
            if(iter.Value == current.Next.Value)
            {
                current.Next = current.Next.Next;
            }

            current = current.Next;
        }    

        iter = iter.Next;
    }
}

Вот решение из книги (автор написал его на java):

Без буфера мы можем выполнять итерацию с два указателя: «текущий» делает нормальный итерация, в то время как «бегун» повторяет через все предыдущие узлы, чтобы проверить дупс. Бегун будет видеть только один дубликат за узел, потому что если бы было несколько дубликаты они были бы уже удалено.

public static void deleteDups2(LinkedListNode head) 
{
    if (head == null) return;

    LinkedListNode previous = head;
    LinkedListNode current = previous.next;

    while (current != null) 
    {
        LinkedListNode runner = head;

        while (runner != current) { // Check for earlier dups
            if (runner.data == current.data) 
            {
                LinkedListNode tmp = current.next; // remove current
                previous.next = tmp;
                current = tmp; // update current to next node
                break; // all other dups have already been removed
            }
            runner = runner.next;
        }
        if (runner == current) { // current not updated - update now
            previous = current;
            current = current.next;
        }
    }
}

Таким образом, мое решение всегда ищет дубликаты для текущего узла до конца, в то время как их решение ищет дубликаты от головы до текущего узла. Я чувствую, что оба решения будут иметь проблемы с производительностью в зависимости от того, сколько дубликатов в списке и как они распределены (плотность и положение). Но в целом: мой ответ почти такой же хороший, как в книге, или он значительно хуже?

8
задан Kiril 28 March 2013 в 21:13
поделиться