更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
T:
题目描述
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。若为空串,返回-1。位置索引从0开始.
这道题目,和以下问题的解决思路类似:
问题:
给定一个字符串,该字符串都是由阿拉伯数字0~9组成,该字符串可能很长(几万,甚至更长),问如何更快的找出所有只出现过一次的数字?
解法相同,而设定场景不同,这就是需要融会贯通的地方。
-
比较笨的一种解法,那就是用一个两层循环来做,看看当前位置的元素是否在后面也出现过。该解法的时间复杂度为 O ( n 2 ) O(n^2) O(n2),当 n n 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;
}
}
更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~