题目:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/5/strings/34/
题目描述:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
案例:
s = "leetcode"
返回 0.
s = "loveleetcode",
返回 2.
注意事项:您可以假定该字符串只包含小写字母。
思路:第一种思路,自己硬想的 ,时间复杂度O(n^2)......好烂。思路看代码。主要是用一个Boolean型的 数组记录字符是否重复。
class Solution {
public int firstUniqChar(String s) {
int len = s.length();
boolean[] flag=new boolean[len]; //下标表示第几个字符,值默认为false
int x=-1;
char[] ch = new char[len];
//如果字符串长度为1。那就返回0
if(len==1){
x=0;
return x;
}
//把字符串变 字符型数组...天啊我只会这招?
for(int i=0; i<ch.length; i++){
ch[i]=s.charAt(i);
}
for(int j=0; j<ch.length; j++){
for(int k=0;k<ch.length;k++){
//遇到自己就不改变标记
if(j==k)
{
flag[j] = false;
}else if(ch[j]==ch[k]){
flag[j] = true; //遇到别人看是否相同,有一个相同就更改标记,立刻跳出。
break;
}
}
}
//从前面开始查标记。如果有立刻 将该索引给传出。
for(int l=0; l<flag.length;l++){
if(flag[l]==false){
x=l;
return x;
}
}
//没有不重复,返回-1
return x;
}
}
第二种看leetcode大神们的:由于字符串只为小写的26个字母(我都没注意这个条件)
利用for循环将字符串每个字母的索引都获得了,如果indexOf 返回值为 -1 .表示没有找到该字母。
如果从前面开始找到的 索引 等于从后面开始找的索引。index== s.lastindexOf() 。说明只有一个字母。
res = -1 是初始值。如果没有返回-1
第一次进入循环。如果 由判断语句,把刚获得的index 付给res;
之后每次循环都会比较 索引大小。最后必然取得是最小的。
时间复杂度为O(n)............
class Solution {
public int firstUniqChar(String s) {
int res = -1;
for(char ch='a'; ch<='z'; ch++) {
int index = s.indexOf(ch);
if(index != -1 && index == s.lastIndexOf(ch)) {
res = res == -1?index:Math.min(res, index);
}
}
return res;
}
}
新增加第三种思路:用一个数组把 小字母-‘a' 的值 来做哈希表。统计遇到重复的键值+1。然后从头开始找键值为1的。
参考 :https://blog.csdn.net/biezhihua/article/details/79720346
public int firstUniqChar(String s) {
int freq[] = new int[26];
for (int i = 0; i < s.length(); i++)
freq[s.charAt(i) - 'a']++;
for (int i = 0; i < s.length(); i++)
if (freq[s.charAt(i) - 'a'] == 1)
return i;
return -1;
}