• 算法导论:字符统计问题


      在ACM之家看到一道有趣的算法题,好多类似华为,Google等IT巨鳄,都以此为模板来考察实习生。

      (1)华为的考题形式是:通过键盘输入一串小写字母(a~z)组成的字符串,编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。如,输入字符串“abacacde”,则输出的过滤结果为“abcde”。

      不是很难的问题,采用枚举法,一个二重循环就可搞定。示例代码如下:

     1 package org.warnier.zhang.demo;
     2 
     3 public class StringFilter {
     4 
     5     public String filter(String origin) {
     6         String result;
     7         if (origin == null) {
     8             result = null;
     9         } else {
    10             char[] chars = origin.toCharArray();
    11             StringBuilder sb = new StringBuilder();
    12 
    13             for (int i = 0; i < chars.length; i++) {
    14                 int j = 0;
    15                 for (; j < i; j++) {
    16                     if (chars[i] == chars[j]) {
    17                         break;
    18                     }
    19                 }
    20                 if (j == i) {
    21                     sb.append(chars[i]);
    22                 }
    23             }
    24             result = sb.toString();
    25         }
    26         return result;
    27     }
    28 }

      官网给出的解决方案更巧妙,如下翻译为了Java版:

     1   public String filter(String origin){
     2         String result;
     3         if(origin == null){
     4             result = null;
     5         }else{
     6             /**
     7              * 判断字符是否出现的标志;
     8              */
     9             boolean[] flags = new boolean[26];
    10             for(int i = 0; i < flags.length; i++){
    11                 flags[i] = false;
    12             }
    13             char[] chars = origin.toCharArray();
    14             StringBuilder sb = new StringBuilder();
    15             /**
    16              * 判断字符是否第一次出现;
    17              */
    18             for(int i = 0; i < chars.length; i ++){
    19                 if(false == flags[chars[i] - 'a']){
    20                     flags[chars[i] - 'a'] = true;
    21                     sb.append(chars[i]);
    22                 }
    23             }
    24             result = sb.toString();
    25         }
    26         return result;
    27     }

      (2)Google的考题形式是:在一个字符串中找到第一个只出现一次的字符,如输入abaccdeff,则输出b。

      如果提前参见过华为面试的实习生是不是就要幸运的多了,在没有算法复杂度的要求下,上面的代码简单修改一下就搞定了。如,  

     1   public String filter(String origin) {
     2         String result = null;
     3         if (origin != null) {
     4             char[] chars = origin.toCharArray();
     5             for (int i = 0; i < chars.length; i++) {
     6                 for (int j = 0; j < i; j++) {
     7                     if (chars[i] == chars[j]) {
     8                         chars[i] = '0';
     9                         chars[j] = '0';
    10                         break;
    11                     }
    12                 }
    13             }
    14             for (int i = 0; i < chars.length; i++) {
    15                 if (chars[i] != '0') {
    16                     result = String.valueOf(chars[i]);
    17                     break;
    18                 }
    19             }
    20         }
    21         return result;
    22     }

      官网也给出了一种全新的解法,翻译为Java版如下:

     1 public String filter(String origin){
     2         String result = null;
     3         if(origin != null){
     4             /**
     5              * 保存字符出现的次数;
     6              */
     7             int[] flags = new int[26];
     8             for(int i = 0; i < flags.length; i++){
     9                 flags[i] = 0;
    10             }
    11             /**
    12              * 统计字符出现的次数;
    13              */
    14             char[] chars = origin.toCharArray();
    15             for(int i = 0; i < chars.length; i++){
    16                 flags[chars[i] - 'a']++;
    17             }
    18             for(int i = 0; i < flags.length; i++){
    19                 if(flags[i] == 1){
    20                     result = String.valueOf((char)('a' + i));
    21                     break;
    22                 }
    23             }
    24         }
    25         return result;
    26     }

      其实,官网给出的答案不难看出与上面华为考题解答的相似处。这从另一个角度说明,这道考题虽然华为,Google的考察角度不同,但是万变不离其宗,解题的过程中要拨开迷雾,看清本质。

      再者,官网的解题策略也是一种巧妙的思路,我曾在自己的一篇博客“分享:GenericCalendar工具类”中,采用类似上述“判断字符是否出现”,“保存字符出现次数”标志量的方式处理平,闰年二月天数的选择问题。

  • 相关阅读:
    有关于* daemon not running.starting it now on port 5037 *ADB
    在android中调用jni,出现ReferenceTable overflow (max=1024)
    15款优秀移动APP产品原型设计工具
    基于Jenkins+git+gradle的android持续集成,jenkinsgradle
    java代码分析及分析工具
    Android客户端SQLite数据库升级方案
    基于Android SQLite的升级
    Android唯一识别码
    Android中获取设备信息的方法
    Android Ubuntu 安装问题FAQ
  • 原文地址:https://www.cnblogs.com/warnier-zhang/p/4485814.html
Copyright © 2020-2023  润新知