有一串随机字符,如' a'''''' a' ...等等。在我查询的任何给定时间点,我需要获得第一个非重复字符。例如,对于输入" abca",' b'应该返回,因为重复,第一个非重复的字符是' b'。
需要有两种方法,一种用于插入,另一种用于查询。
我的解决方案是使用linkedList存储传入的流字符。当我得到下一个字符时,我只是与所有当前字符进行比较,如果存在,我将不会插入到链表的末尾,否则我将在最后插入。通过这种方法,查询将采用O(1),因为我将得到链表上的第一个元素,插入将采用O(n),因为我需要从第一个元素到最坏情况下的最后一个元素进行比较。
有没有更好的演出方式?
答案 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;
}
}