剑指笔记——50 第一个只出现一次的字符

题目1:字符串中第一个只出现一次的字符
在字符串中找出第一个只出现一次的字符。如输入”abaccdeff”,则输出’b’。

思路1:剑指中的思路如下:我们扫描两次字符串。第一次的时候统计每一个字符在字符串中出现的次数;第二次的时候扫描字符串,第一个出现次数为1的字符就是我们要找的。在统计字符次数的时候我们使用一个简单的哈希表。字符是一个长度为8的数据类型,因此一共有256中可能。因此我们创建一个长度为256的数组,每一个字母根据其ASCII码值作为数组下边对应数组的一个数字,数组中存储的就是对应字符出现的位置。

我之前想错了,以为第二次扫描是直接对数组进行扫描,这样就存在字母顺序问题了。但实际上是扫描字符串。这个代码的时间复杂度是O(n),空间复杂度是O(1)

代码来源:https://blog.csdn.net/m0_37862405/article/details/80377886

代码1:

public class FirstNotRepeatingChar
{
   private static char findFirstChar(String string)
    {
        if (string == null || string.equals(""))

                   return '\0';  //返回字符0
        int[] records = new int[256];
        for (int i = 0; i < string.length(); i++)
        {
            records[string.charAt(i)]++;
        }
        for (int i = 0; i < string.length(); i++)
        {
            char curChar = string.charAt(i);
            //返回第一个只出现一次的字符
            if (records[curChar] == 1)

              return curChar;
        }
        return '\0';
    }
}

题目2:字符流中第一个只出现一次的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’

思路2:和上面的题目1不同的是,这是一个字符流。字符只能一个接着一个从流中读取出来,不能像上面的题目一样整体全部扫描。我们可以和上面的题一样使用一个数组表示的哈希表存储字符第一次出现的位置。首先初始化的时候,将数组元素均初始化为-1,若一个字符多次出现,将其置为-2.最后我们可以检查哈希表中的数据,找出出现最早的那个字符。这种思路的时间复杂度是O(n),空间复杂度是O(1)。

代码来源:https://blog.csdn.net/m0_37862405/article/details/80378040

代码2:

public class FirstAppearingOnceChar
{
    private static int[] positionRecords; //字符读出位置记录
    private static int position;  //字符的读出位置

    static   //静态块进行初始化
    {
        positionRecords = new int[256];
        for (int i = 0; i < positionRecords.length; i++)
        {
            positionRecords[i] = -1;  //初始化为-1
        }
        position = 0;
    }

  //从字符流中读出字符
    private static void insert(char ch)
    {
        if (positionRecords[ch] == -1)  //如果之前没有出现过,记录当前的位置
            positionRecords[ch] = position;  //记录读出位置
        else if (positionRecords[ch] >= 0)  //如果之前出现过,重新赋值为-2
            positionRecords[ch] = -2;  //该字符出现多次
        position++;
    }

    //字符流中第一个只出现一次的字符
    private static char firstAppearingOnceChar()
    {
        char result = '#';
        int minIndex = Integer.MAX_VALUE;  //非重复字符最早出现的位置,先赋值一个已知的最大值
        for (int i = 0; i < positionRecords.length; i++)
        {
            if (positionRecords[i] >= 0 && positionRecords[i] < minIndex)
            {
                result = (char) i;   //把整型转变为字符型
                minIndex = positionRecords[i];
            }
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/chenxy132/article/details/89482263