Подтвердить что ты не робот

Поиск первого не повторяющегося символа строки в O (n) с использованием булевого массива?

Мой вопрос связан с этим ранним вопросом

Найти первый повторный символ в строке.

В одном из моих интервью мне было предложено написать функцию, чтобы определить первый уникальный символ в строке во времени O (n), используя в качестве дополнительного пространства только булевский массив длины n. То есть, найдите первую не повторяющуюся букву в строке, используя только сложность O (n) и массив bool длины n. Может ли кто-нибудь предложить, как его решить с помощью массива bool?

4b9b3361

Ответ 1

Ну, если размер набора символов является постоянным... Скажем, например, 0-255...

Сканировать строку, ищущую символ 0.

Затем сканируйте строку, которая ищет символ 1.

Затем сканируйте строку, которая ищет символ 2.

...

Наконец, сканируйте строку, которая ищет символ 255.

Это занимает 256 * n операций, которые являются O (n).

Во время каждого сканирования, если символ уникален, отметьте его положение в растровом изображении. В конце верните символ в первую отмеченную позицию. (Или просто записать первый уникальный символ и его местоположение с помощью бит k + log (n). Используйте жестко закодированную таблицу поиска или что угодно для очень маленького n, в противном случае n бит великодушны.)

Хотя почему-то я подозреваю, что это не то, что имел в виду интервьюер.

Ответ 2

    private static void FirstNonRepeatingCharacters()
    {
        string s = "abbazccdde";
        var result = from item in s
                     group item by item into groupedItems
                     where groupedItems.Count() == 1
                     select groupedItems.Key;
        Console.WriteLine(result.First());                    
    }

Реализация С#

Ответ 3

Для решения с одним проходом

Поддерживать 2 структуры данных:

  • Array/bitmap/hashtable для отслеживания количества символов
  • LinkedHashMap для отслеживания символов, которые произошли только один раз.

LinkedHashMap имеет

  • O (1) вставка
  • O (1) удаление
  • O (1) поиск

    class Node
    {
      char data;
      Node next;
      Node prev;
    };
    
    class LinkedHashMap
    {
            // This will keep the insertion order intact
            Node listHead;
            Node currentTail = listHead;
            HashTable<char, Node> charExistsMap;
    
        void Add(char ch) 
        {
            if(!charExistsMap.ContainsKey(ch)) 
            {
                // Add to both hashtable and linkedlist
                Node n = new Node(ch);
                n->next = null;
                n->prev = curentTail; // Added To List
                currentTail = n;
                charExistMap.Add(ch, n);
            }
            else 
            {
                // Remove from both hashtable and linkedlist
                Node n = charExistMap.Remove(ch);
                if(n->prev != null) 
                {
                    n->prev->next = n->next
                    listHead = n->next; // update head
                }
                if(n->next != null)
                    n->next->prev = n->prev;
             }
        }
    
        char GetFirstNonRepeatingChar()
        {
            return listHead->data;
        }
    

    }

После прохождения исходной строки глава LinkedHashMap будет содержать первый символ, который не повторяется.

Ответ 4

public class FirstUniqueChar {

  public static void main(String[] args) {

    String test = "ABxacd";

    test = test.toUpperCase();
    for (int i = 0; i < test.length(); i++) {
        int firstIndex = test.indexOf(test.charAt(i));
        int lastIndex = test.lastIndexOf(test.charAt(i));
        if (firstIndex == lastIndex) {
            System.out.println("First unique char of String " + test.charAt(i));
            break;
        }

    }

  }
}

Ответ 5

Сделайте это за два прохода:

1-й проход: создайте массив bool размером 256 и для каждого char в текстовой пометке элемент index int (который char). Это берет O (n).

2-й проход: для каждого char в тексте проверьте, отмечен ли соответствующий элемент массива. Если нет, тогда вы нашли свой ответ. Это также принимает O (n).

Ответ 6

Имейте два булевых массива, увиденных и увиденных. Цикл по строке заполняет массивы. Перебирайте строку, снова проверяя, присутствует ли символ вначале, но не отображается много. Если это ваш первый неповторяющийся символ.

Вот пример кода в python.

subject = "ttojxxlma"

seenOnce = [False for i in range(256)]
seenMany = [False for i in range(256)]

for c in subject:
    index = ord(c)
    if seenOnce[index] == False:
        seenOnce[index] = True
    else:
        seenMany[index] = True

for c in subject:
    index = ord(c)
    if seenOnce[index]==True and seenMany[index] != True:
        print(c)
        break

Хорошо, что все еще использует слишком логический массив (или списки python = P). Чтобы использовать только один массив, у вас может быть один массив, который удваивает количество символов. Вместо доступа к второму массиву удвоить индекс и получить доступ к большому. Но это просто грязно.

Не уверен, что это можно сделать с меньшим объемом.