- 前言:
java里new一个新数组,eg:int[] a=new int[30],初始值是默认全为0的。
这题用了hash思想,原来也不一定用到hash这个关键字
hashmap的底层是散列表,数据的存储与插入顺序无关,比如依次put的是q,w,e字符,遍历的时候可能是e,w,q顺序的。而linkedhashmap底层有一个双链表来维护其存储顺序,遍历的时候是按照插入顺序来遍历的
- 题目:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
- 思路:
3.1 一直用数组比较多,所以这次还是用数组做出来了,但是答案也不如大佬们用hash表来做的,先说一下自己的思路,毕竟能做出来也是开心的:两个数组,一个从来存储单次出现的字符,一个用来存储多次(大于1次)的字符。把各字符依次与这两个数组比较。
3.2 hash思想的思路:(两种,一种用到hash来存储数据,一种用数组来存储)(**完全可以直接建个256长度的数组,因为acsii码总共就256个,这样就不用下标-65了。**参考test54也行)
用hash和ASCII码来解决,也是学到了,建个数组,下标0-58,值均为0,依次代表a-z,A-Z(A-Z得ASCII值是65-90,a-z得ASCII值是97-122.122-65+1=58,中间断档,有几个用不,无所谓)。然后我遍历字符串,比如输入A,我们就求得它的ascii—65,为0,这样数组下标为0的地方的值就+1。即,建个数组,数组的下表代表各字母,值代表出现的次数,就形成了键值对。
3.3 用hashmap来存储键值对信息,键即字母,值即次数。存储完了后,找值为1的,但是只能通过str遍历来找,不能自己遍历hashmap来找第一个值为1的,然后输出下标。因为hashmap不一定按顺序存储的。Linkedhashmap是按顺序存储的,所以选择不同的map,有不同的遍历方法。
- 代码:
我的:
package cn.test34;
import java.util.ArrayList;
import java.util.List;
public class test {
public static void main(String[] args){
String str="abcdefgbbcddeas";
Solution solution=new Solution();
System.out.println(solution.FirstNotRepeatingChar(str));
}
}
class Solution {
public int FirstNotRepeatingChar(String str) {
if(str.length()==0) return -1;//字符串为空,返回-1;
List<Character> repeat=new ArrayList<Character>();//记录已经出现了2次及以上的字符
List<Character> simple=new ArrayList<Character>();//记录只出现了一次的字符
for(int i=0;i<str.length();i++){
Character a=str.charAt(i);//记录当前字符
//如果repeat里包含字符a,则结束循环,如果repeat里没有,且simple里有,则说明这个字符第二次出现,从
//simple里删除它,并加入到repeat里。如果repeat和simple里都没有,则加入simple里。
if(repeat.contains(a)){
continue;
}else if(simple.contains(a)){
simple.remove(a);
repeat.add(a);
}else{
simple.add(a);
}
}
//返回simple数组第一个字符在str里的位置
if(simple.size()==0) return -1;
else return (str.indexOf(simple.get(0)));
}
}
大佬们用hash的代码,自己也学者写了下,得熟悉用hash,最近做题发现用得也多,也很实用。
class Solution1 {
public int FirstNotRepeatingChar(String str) {
//因为区分大小写,A-Z得ASCII值是65-90,a-z得ASCII值是97-122.122-65+1=58
//数组从前到后(除去中间几个)依次代表A-Z,a-z的值
int[] words=new int[58];
//循环遍历
for(int i=0;i<str.length();i++){
words[(int)str.charAt(i)-65]+=1;
}
//看各字母,谁的计数为1
for(int i=0;i<str.length();i++){
if(words[(int)str.charAt(i)-65]==1) return i;
}
return -1;
}
}
用到hash结构的代码:
class Solution2 {
public int FirstNotRepeatingChar(String str) {
Map<Character,Integer> map =new HashMap<Character,Integer>();
for(int i=0;i<str.length();i++){
if(map.containsKey(str.charAt(i))){
int time=map.get(str.charAt(i));//看看当前字符的值,即次数
map.put(str.charAt(i),++time);//新的值会覆盖旧的值
}else{
map.put(str.charAt(i),1);
}
}
for(int i=0;i<str.length();i++){
if(map.get(str.charAt(i))==1){
return i;
}
}
return -1;
//再查找
}
}