面试题35. 第一个只出现一次的字符

来源:互联网 发布:19楼网络股份有限公司 编辑:程序博客网 时间:2024/06/04 23:12

题目描述
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。
如:输入”abaccdeff”,则输出’b’的位置 1

思路1: 从头开始遍历字符串中的字符,向后逐个比较,如果没有发现重复的字符,说明当前字符就是第一次出现的字符,就返回当前字符的位置。如果有 n 个字符,时间复杂度是O(n2)

思路2:
由于题目说,字符串中的字符全部由字母组成,也就是说包括大写字母和小写字母。这些字母的一共有52个A~Z,a~z,可以借助一个大小为52的字符数组,数组中每一位对应一个字符,见下图:

这里写图片描述

整个算法需要遍历两次字符串:
第一次遍历,修改数组中 字符对应位置的值,把值加1;
第二次遍历,如果数组中 字符对应位置的值等于1,说明该字符就是第一次出现的字符。
时间复杂度O(n)

Java 代码如下:

public class Solution {    public int FirstNotRepeatingChar(String str) {        if("".equals(str)) {            return -1;        }        char[] arr = new char[52];        int len = str.length();        // 第一次遍历        for(int i = 0; i < len; i++) {            char c = str.charAt(i);            if(c >= 'a' && c <= 'z') {                arr[c - 'a' + 26]++;            }else if(c >= 'A' && c <= 'Z') {                arr[c - 'A']++;            }        }        // 第二次遍历        int index = 0;        for(int i = 0; i < len; i++) {            char c = str.charAt(i);            if(c >= 'a' && c <= 'z' && arr[c - 'a' + 26] == 1) {                index = i;                break;            }else if(c >= 'A' && c <= 'Z' && arr[c - 'A'] == 1) {                index = i;                break;            }        }        return index;    }}

注意: 空字符串 、不合法的输入

扩展题目:

1、输入两个字符串,从第一个字符串中删除存在于第二个字符串中的字符。

可以把第二个字符串中的字符存放在HashSet中,然后遍历第一个字符串,这样就能在O(1)的时间内,判断出该字符是否在第二个字符串中。

2、输入一个字符串,删除这个字符串中重复的字符。

3、判断两个单词是否是“变位词”(listen与silent、evil与live)

用一个HashMap,key是字符,value是字符出现的次数。首先遍历第一个单词,对应的字符出现次数加1。然后遍历第二个单词,对应字符出现的次数减1。如果HashMap中所有的value都是0,那么就是“变位词”

这里写图片描述

原创粉丝点击