关闭

《剑指offer》——第一个只出现一次的字符位置

标签: 算法java牛客剑指offer
308人阅读 评论(0) 收藏 举报
分类:

T:

题目描述
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。若为空串,返回-1。位置索引从0开始.

这道题目,和以下问题的解决思路类似:

问题:

给定一个字符串,该字符串都是由阿拉伯数字0~9组成,该字符串可能很长(几万,甚至更长),问如何更快的找出所有只出现过一次的数字?

解法相同,而设定场景不同,这就是需要融会贯通的地方。

  • 比较笨的一种解法,那就是用一个两层循环来做,看看当前位置的元素是否在后面也出现过。该解法的时间复杂度为O(n2),当n很大的时候,那是相当的不能忍啊。。。

  • 还一种相对容易一些的方法,就是先遍历一遍,统计各个元素出现的次数,再在统计数据中找出数值为1的元素。

那么问题的关键就是在这个统计结构的设计了,如何设计?也许用一个二维数组,那么,如果元素不是阿拉伯数字,而是字母怎么办?这是相对麻烦的一种,幸好java都已经做了封装,我们可以用hashMap,或者hashSet来解决。

如果用c语言来实现,又该怎么破?没有封装好的哈希来调用,只能寻求其他方法。如果是阿拉伯数字,那么统计结构就可以设计成为一个长度为10的一维整型数组,字符串中出现的阿拉伯数字就可用来代表其在整型数组中的下标,问题迎刃而解,省时省力省空间。如果不是阿拉伯数字,而是字母,那就设定一个长度为26的整型一维数组。

先给出一个hashMap版本的:

code:

    import java.util.HashMap;

    /**
     * T: 第一个只出现一次的字符位置
     * 
     * 题目描述 
     * 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。
     * 若为空串,返回-1。位置索引从0开始.
     * 
     * date: 2015.11.17  21:16
     * @author SSS
     *
     */
    public class Solution {

        /**
         * 设立一个hashMap,将每个字母出现的次数进行统计。
         * 若要找出第一个,就要对string从头开始再次遍历一遍,
         * 找到其在hashMap中的value值为1,则返回其下标
         * @param str
         * @return
         */
        public int FirstNotRepeatingChar(String str) {

            int index = -1;
            if (str == null || str == "") {
                return index;
            }

            HashMap<Character, Integer> statisticsMap = new HashMap<Character, Integer>();

            // 第一次遍历,统计每个字符出现的个数
            for (int i = 0; i < str.length(); i++) {
                Character tempChar = str.charAt(i);
                if (statisticsMap.get(tempChar) == null) {
                    statisticsMap.put(tempChar, 1);
                } else {
                    int tempCount = statisticsMap.get(tempChar) + 1;
                    statisticsMap.remove(tempChar);
                    statisticsMap.put(tempChar, tempCount);
                }
            }

            // 第二次遍历,找出第一个只出现一次的字符的下标位置
            for (int i = 0; i < str.length(); i++) {
                Character tempChar1 = str.charAt(i);
                if (statisticsMap.get(tempChar1) == 1) {
                    index = i;
                    break;
                }
            }

            return index;
        }
    }

再来第二种用数组统计的方式:

code:

    import java.util.HashMap;

    /**
     * T: 第一个只出现一次的字符位置
     * 
     * 题目描述 
     * 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。
     * 若为空串,返回-1。位置索引从0开始.
     * 
     * date: 2015.11.17  21:16
     * @author SSS
     *
     */
    public class Solution {

        /**
         * 另一种方式,用数组进行统计
         * @param str
         * @return
         */
        public int FirstNotRepeatingChar(String str) {
            int index = -1;
            if (str == null || str == "") {
                return index;
            }

            // 创建一个数组进行统计
            int []countArr = new int[26];
            // 初始化
            for (int i = 0; i < countArr.length; i++) {
                countArr[i] = 0;
            }

            // 本题目比较坑的地方,都是大写或者都是小写,先进行判断
            char tempChar = 'a';
            if (str.charAt(0) < tempChar) {
                tempChar = 'A';
            }
            // 进行统计
            for (int i = 0; i < str.length(); i++) {
                int tempIndex = str.charAt(i) - tempChar;
                int nums = countArr[tempIndex];
                countArr[tempIndex] = nums + 1;
            }

            // 在原字符串中找出该字符第一次出现的地方,记录其下标,中断for循环
            for (int i = 0; i < str.length(); i++) {
                if (countArr[str.charAt(i) - tempChar] == 1) {
                    index = i;
                    break;
                }
            }

            return index;
        }
    }
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:39727次
    • 积分:1146
    • 等级:
    • 排名:千里之外
    • 原创:79篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类