zoukankan      html  css  js  c++  java
  • 一个字符串中找到第一个只出现一次的字符

    题目描述:

      在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符。 如输入 abaccdeff,则输出 b。

    输入:

      输入有多组数据
      每一组输入一个字符串。

    输出:

      输出第一个只出现一次的字符下标,没有只出现一次的字符则输出-1

    我们这里有两种解题思路

    1.蛮力法。

      遍历数组,每找到一个字符是遍历一下整个数组,看看该字符是否存在数组下表不一致,但是ASSIC码值一样的字符还存在,如果不存在,则是返回该字符,如果存在,则继续遍历。该算法的时间复杂度为O(n*n),显然这样的效率不是很高。

     1 /**
     2      * 利用两次循环,时间复杂度O(n*n)
     3      * 
     4      * @author yfy
     5      * @param args
     6      *            需要查找的字符串
     7      * @param len
     8      *            字符串长度
     9      * @return 返回第一个出现一次字符的ASSIC码值,如果没有只出现一次的字符,则返回-1
    10      */
    11     int firstNotRepeatingChar(char[] args, int len) {
    12         int j;
    13         for (int i = 0; i < len; i++) {
    14             for (j = 0; j < len; j++) {
    15                 if (i != j) {
    16                     if (args[i] == args[j]) {
    17                         break;
    18                     }
    19                 }
    20             }
    21             // 沒有找到和这个字符相等的字符。
    22             if (j == len) {
    23                 return args[i];
    24             }
    25         }
    26         return -1;
    27     }
    View Code

     2.空间换时间

    利用hash表,把字符串照中出现的字符,映射到hash表中,并统计每个字符出现的次数,再次遍历字符串的每次字符,直到找到第一个出现一次的字符。算法时间复杂度O(n)。

     1 /**
     2      * 利用hash表,把每次字符做成对hash的映射
     3      * 
     4      * @author yfy
     5      * @param args   需要查找的字符串
     6      * @param len    字符数组长度
     7      * @return     返回第一个出现一次字符的ASSIC码值,如果没有只出现一次的字符,则返回-1
     8      */
     9     int firstNotRepeatingChar(char[] args, int len) {
    10 
    11         // 定义一个hash长度为 ASSIC码值长度+1
    12         int[] hash = new int[128];
    13 
    14         // 把字符数组映射到hash表中
    15         for (int i = 0; i < len; i++) {
    16             hash[args[i]]++;
    17         }
    18 
    19         // 再次遍历数组,找到第一个出现一次的字符。
    20         for (int i = 0; i < len; i++) {
    21             if (hash[args[i]] == 1) {
    22                 char ch = args[i];
    23                 return ch;
    24             }
    25         }
    26 
    27         // 没有找到出现出现一次的字符
    28         return -1;
    29     }

    算法改进

      在上面这个算法中,我们的时间复杂度为O(n),但是我们要对字符数组遍历两次,如果字符数组数量很大,遍历两次还是有点多呢,可以不可以只遍历一次呢。当然是可以的,因为我们查找的ASSIC码中的字符,那么最多可能有128种字符,可以把出现过的字符按先后顺序都记录在一个字符数组中,我们第二次遍历只需要遍历这个字符数组中出现次数为一的字符。

     1 /**
     2      * 利用hash表,把每次字符做成对hash的映射
     3      * 
     4      * @author yfy
     5      * @param args   需要查找的字符串
     6      * @param len    字符数组长度
     7      * @return        返回第一个出现一次字符的ASSIC码值,如果没有只出现一次的字符,则返回-1
     8      */
     9     int firstNotRepeatingChar2(char[] args, int len) {
    10         // 定义一个hash长度为 ASSIC码值长度
    11         int[] hash = new int[128];
    12 
    13         char[] exsited = new char[128];
    14         int count = 0;
    15 
    16         // 把字符数组映射到hash表中
    17         for (int i = 0; i < len; i++) {
    18 
    19             // 如果这个字符是第一次出现,则把该字符放入字符数组exsited中
    20             if (hash[args[i]] == 0) {
    21                 exsited[count++] = args[i];
    22             }
    23             hash[args[i]]++;
    24         }
    25 
    26         // 遍历数组exsited,找到第一个出现一次的字符。
    27         for (int i = 0; i < count; i++) {
    28             if (hash[exsited[i]] == 1) {
    29                 char ch = args[i];
    30                 return ch;
    31             }
    32         }
    33         // 没有找到出现出现一次的字符
    34         return -1;
    35     }
  • 相关阅读:
    Java 7 新的 try-with-resources 语句,自动资源释放
    单例模式在多线程下的问题
    设计模式-结构型模式
    设计模式-创建型模式
    【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案·续·装饰器
    【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案
    启动流程--CPU启动条件
    特殊估计制作(2): dump固件
    内存泄漏:lowmemory 相关调试
    寄存器调试 (2):应用层通过C代码访问
  • 原文地址:https://www.cnblogs.com/yfyzy/p/4724944.html
Copyright © 2011-2022 走看看