找到第一个非重复字符,花费O(n)

时间:2016-09-15 10:16:06

标签: java

首先,我知道如果string包含Ascii table,如何找到第一个不重复的字符,例如:`" abccba .."

问题或问题是:如何找到string/buffer中的第一个非重复字符包含混合字母?我的意思是我们不知道语言是什么! 也许是英语阿拉伯语两种语言之间的混合,我必须在 O(n)中这样做

  • 如果我们使用HashMap,那么getput费用为O(1) [PROVE]?
  • 什么样的输入!是string还是其他容器?

3 个答案:

答案 0 :(得分:0)

制作一张计算出现次数的<Character, Integer>地图,一次逐个字符地查看整个字符串,如果它不存在(数量为1),则将其添加到地图中,或者增加发生的次数,如果已经存在的话。然后再次遍历整个String,并返回您找到的第一个有计数的项目。此处不需要计算出现次数,可以用不同的方式完成,也可以在2处停止,但如果你正在尝试,它可能会很有用稍后扩展您的代码以执行更多操作。当然,如果你使用阿拉伯语字母,你需要处理潜在的unicode问题,但我认为这不是你所问的问题。这个解决方案是O(N),你要经历你的String 2次,并且地图操作更便宜。

答案 1 :(得分:0)

如果HashMap解决方案不够好,我可以想到:创建java.util.BitSetseenOnceseenTwice的两个实例,每个实例都有0x10000位。对于每个字符,如果它已在seenOnce中,请将其添加到seenTwice,否则将其添加到seenOnce。第二次打败字符串,打印出不在seenTwice中的第一个字符。

答案 2 :(得分:0)

C#... 中,O(n)时间复杂度...

public char GetFirstRecuringChar(string text)
{
    if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text))
    {
        throw new ArgumentNullException();
    }

    IDictionary<char, CharIndex> map = new Dictionary<char, CharIndex>();

    for (int i = 0; i < text.Length; i++)
    {
        if (map.ContainsKey(text[i]))
        {
            map[text[i]].Count++;
        }
        else
        {
            CharIndex ci = new CharIndex { Index = i, Ch = text[i], Count = 1 };
            map.Add(text[i], ci);
        }
    }

    int lowestIndex = int.MaxValue;
    foreach (CharIndex charIndex in map.Values)
    {
        if (charIndex.Count == 1)
        {
            if (lowestIndex > charIndex.Index)
            {
                lowestIndex = charIndex.Index;
            }
        }
    }

    char answer = '\n';
    if (lowestIndex != int.MaxValue)
    {
        foreach (CharIndex charIndex in map.Values)
        {
            if (charIndex.Index == lowestIndex)
            {
                answer = charIndex.Ch;
                break;
            }
        }
    }

    return answer;
}

private class CharIndex
{
    public char Ch { get; set; }
    public int Index { get; set; }
    public int Count { get; set; }
}

单元测试:

[TestCase("ississippitotalm", 'o')]
[TestCase("a", 'a')]
[TestCase("teeter", 'r')]
[TestCase("teeterxyz", 'r')]
[TestCase(".......................................x.................f.........y...xkiuytreeee", 'f')]
public void GetFirstRecuringCharTest(string text, char expectedAnswer)
{
    char result = runner.GetFirstRecuringChar(text);
    Assert.That(result, Is.EqualTo(expectedAnswer));
}