【算法学习】求字符串中第一个出现最少的字符(java)

来源:互联网 发布:js对象 extend 编辑:程序博客网 时间:2024/06/08 04:39

最近参加某公司二面,出了个算法题“求字符串中第一个出现最少的字符”,一时蒙了,,居然木有想出来,再加上没有熟悉的IDE没手感(真心感觉,敲java需要手感,哈哈可能我还很水)


【方案1】原始方法

(1)申请一个数组,与字符串等长
(2)循环字符串,对每个字符串进行(3)操作
(3)将字符与字符串中的所有字符进行比对(是否包含自身无所谓),并记录出现个数
(4)遍历统计统计结果,求得最少出现的(第一个很简单,使用打擂法很容易排除后面与之相等的情况。)

参考代码如下:

   /**     * 原始办法,逐个匹配     *     * @param chars     * @return     */    private static char function0(char[] chars) {        int arrayResult[] = new int[chars.length];//某个字符出现重复数。默认为0        for (int i = 0; i < chars.length; i++)            for (int j = 0; j < chars.length; j++)                if (chars[j] == chars[i]) arrayResult[i]++;        int num = 0;        for (int i = 1; i < chars.length; i++)            if (arrayResult[num] > arrayResult[i]) {                num = i;            }        return chars[num];    }

看似代码量比较少,,实际运行效率很差的。


【方案2】备忘录法

在原始方法基础上添加备忘录,
(1),申请一个数组,与字符串等长
(2),循环字符串,对每个字符串进行(3)操作
(3),从当前位置的下一个开始,向后匹配,当遇到相同数时停下,将当前字符出现次数加1赋值给改字符(相当于做了一个备忘录),并对当前字符做特殊标记,表示后面还有出现。

参考代码:

   /**     * 【1】,申请一个长度为chars.length,用来记录每个字符出现的次数     * 【2】,对chars进行遍历,比对每个字符,统计其出现个数     * 【3】,从当前位置的下一个开始,向后匹配,当遇到相同数时停下,     * 将当前字符出现次数加1赋值给改字符(相当于做了一个备忘录),     * 并对当前字符做特殊标记,表示后面还有出现。     *     * @param chars     * @return     */    private static char function1(char[] chars) {        int arrayResult[] = new int[chars.length];        for (int i = 0; i < chars.length; i++) {            if (arrayResult[i] < 1) arrayResult[i] = 1;//置为1,,某个字符至少一个            for (int j = i + 1; j < chars.length; j++)                if (chars[j] == chars[i]) {                    arrayResult[j] = arrayResult[i] + 1;                    arrayResult[i] = -1;//-1标记代表改字符后面还有字符                    break;                }        }        int num = 0;        for (int i = 1; i < chars.length; i++)            if (arrayResult[i] > 0 && arrayResult[num] > arrayResult[i]) {                num = i;            }        return chars[num];    }

去掉注释,,代码量也比较少(浓缩就是精华。)


【方案3】

利用hashmap,,把字符依次放入hash表中,如果存在该字符的key,则value++

   /**     * 利用hashmap,,把字符依次放入hash表中,如果存在该字符的key,则value++     *     * @param chars     * @return     */    private static char function2(char[] chars) {        //创建hashmap        Map<Character, Integer> charMap = new HashMap<>();        for (int i = 0; i < chars.length; i++) {            if (charMap.containsKey(chars[i]))                charMap.put(chars[i], charMap.get(chars[i]) + 1);            else                charMap.put(chars[i], 1);        }        int num = 0;        for (int i = 1; i < chars.length; i++)            if (charMap.get(chars[num]) > charMap.get(chars[i])) {                num = i;            }        return chars[num];    }

这个方法,,,算是最容易实现的,,不过借助了库函数(不是很好哦),,玩的是算法。


三种方案对比

【方案1】
比较低端,,几乎没有使用任何优化手段,只是做了简单的匹配。

【方案2】
中高端,使用到了备忘录的方法(类似动态规划),对检索进行优化,很适用于重复率较高的串

【方案3】
巧妙利用库函数,不过算法方面体现的不是很到位,业务代码中使用比较合适(当然自己优化更好)



三种方案运行时间对比。(博主使用 jdk1.8,IDEA2016)

这里写图片描述

这里写图片描述

这里写图片描述

很明显备忘录法优势杠杠的。(原因是测试串重复率很高)



完整测试代码如下

package algorithm_2;import java.util.HashMap;import java.util.Map;/** * Created by zsl on 2017/8/24. * 求字符串中第一个出现最少的字符 */public class StringFindFirstLess {    public static void main(String[] args) {        String str = "首aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天" +                "aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天aabbccddacd今天尾";        //测试本办法,花费时间        char result = 0;        long start = System.currentTimeMillis();        result = function0(str.toCharArray());        long end = System.currentTimeMillis();        System.out.println("所求字符为:" + result);        System.out.println("【原始方法】运行时间:" + (end - start) + "毫秒");//应该是end - start        //加入备忘录,花费时间        start = System.currentTimeMillis();        result = function1(str.toCharArray());        end = System.currentTimeMillis();        System.out.println("所求字符为:" + result);        System.out.println("【备忘录法】运行时间:" + (end - start) + "毫秒");//应该是end - starti        //使用HashMap,花费时间        start = System.currentTimeMillis();        result = function2(str.toCharArray());        end = System.currentTimeMillis();        System.out.println("所求字符为:" + result);        System.out.println("【HashMap法】运行时间:" + (end - start) + "毫秒");//应该是end - starti    }    /**     * 原始办法,逐个匹配     *     * @param chars     * @return     */    private static char function0(char[] chars) {        int arrayResult[] = new int[chars.length];//某个字符出现重复数。默认为0        for (int i = 0; i < chars.length; i++)            for (int j = 0; j < chars.length; j++)                if (chars[j] == chars[i]) arrayResult[i]++;        int num = 0;        for (int i = 1; i < chars.length; i++)            if (arrayResult[num] > arrayResult[i]) {                num = i;            }        return chars[num];    }    /**     * 【1】,申请一个长度为chars.length,用来记录每个字符出现的次数     * 【2】,对chars进行遍历,比对每个字符,统计其出现个数     * 【3】,从当前位置的下一个开始,向后匹配,当遇到相同数时停下,     * 将当前字符出现次数加1赋值给改字符(相当于做了一个备忘录),     * 并对当前字符做特殊标记,表示后面还有出现。     *     * @param chars     * @return     */    private static char function1(char[] chars) {        int arrayResult[] = new int[chars.length];        for (int i = 0; i < chars.length; i++) {            if (arrayResult[i] < 1) arrayResult[i] = 1;//置为1,,某个字符至少一个            for (int j = i + 1; j < chars.length; j++)                if (chars[j] == chars[i]) {                    arrayResult[j] = arrayResult[i] + 1;                    arrayResult[i] = -1;//-1标记代表改字符后面还有字符                    break;                }        }        int num = 0;        for (int i = 1; i < chars.length; i++)            if (arrayResult[i] > 0 && arrayResult[num] > arrayResult[i]) {                num = i;            }        return chars[num];    }    /**     * 利用hashmap,,把字符依次放入hash表中,如果存在该字符的key,则value++     *     * @param chars     * @return     */    private static char function2(char[] chars) {        //创建hashmap        Map<Character, Integer> charMap = new HashMap<>();        for (int i = 0; i < chars.length; i++) {            if (charMap.containsKey(chars[i]))                charMap.put(chars[i], charMap.get(chars[i]) + 1);            else                charMap.put(chars[i], 1);        }        int num = 0;        for (int i = 1; i < chars.length; i++)            if (charMap.get(chars[num]) > charMap.get(chars[i])) {                num = i;            }        return chars[num];    }}
阅读全文
0 0