优化数据结构实现

时间:2015-07-16 15:54:12

标签: algorithm data-structures

有一串随机字符,如' a'''''' a' ...等等。在我查询的任何给定时间点,我需要获得第一个非重复字符。例如,对于输入" abca",' b'应该返回,因为重复,第一个非重复的字符是' b'。

需要有两种方法,一种用于插入,另一种用于查询。

我的解决方案是使用linkedList存储传入的流字符。当我得到下一个字符时,我只是与所有当前字符进行比较,如果存在,我将不会插入到链表的末尾,否则我将在最后插入。通过这种方法,查询将采用O(1),因为我将得到链表上的第一个元素,插入将采用O(n),因为我需要从第一个元素到最坏情况下的最后一个元素进行比较。

有没有更好的演出方式?

1 个答案:

答案 0 :(得分:3)

要么你没有很好地解释你的算法,要么它不会返回正确的结果。在示例a b a中,您的算法会返回a(因为它是链接列表中的第一个元素)吗?

无论如何,这是一个改进性能的修改。这个想法是使用从字符到(双重)链表节点的哈希映射。此映射可用于确定是否已插入字符并快速到达所需节点。我们应该允许地图目标(而不是列表节点)的null值表示已经多次出现的字符。

插入方法的工作原理如下:

检查地图是否包含当前字符( O(1))。如果没有,请将其添加到列表的末尾并添加对地图的引用( O(1))。

如果角色已经在地图中:检查指向的节点是否为null O(1))。如果是这样,请忽略它。如果不是,请从列表中删除指向的节点,并将引用更新为null值( O(1))。

总体而言, O(1)操作。

查询的工作方式与之前的解决方案相同。

这是一个C#实现。它基本上是上述解释的1:1翻译:

class StreamAnalyzer
{
    LinkedList<char> characterList = new LinkedList<char>();
    Dictionary<char, LinkedListNode<char>> characterMap 
        = new Dictionary<char, LinkedListNode<char>>();

    public void AddCharacter(char c)
    {
        LinkedListNode<char> referencedNode;
        if (characterMap.TryGetValue(c, out referencedNode))
        {
            if(referencedNode != null)
            {
                characterList.Remove(referencedNode);
                characterMap[c] = null;
            }
        }
        else
        {
            var node = new LinkedListNode<char>(c);
            characterList.AddLast(node);
            characterMap.Add(c, node);
        }
    }

    public char? GetFirstNonRepeatingCharacter()
    {
        if (characterList.First == null)
            return null;
        else
            return characterList.First.Value;
    }
}