LeetCode

来源:互联网 发布:广发证券软件 编辑:程序博客网 时间:2024/06/05 06:02

题目
Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.
Note: You may assume the string contain only lowercase letters.
思路1
可以建立一个哈希表,保存每一个字符的出现的位置,重复出现的字符可以用一个特殊的值,比如INT_MAX来表示。最后历遍整个表查找最小的值,也就是从未重复出现过的最靠前的字符位置。

class Solution {public:    int firstUniqChar(string s) {        unordered_map<char,int> strmap;        for(int i=0;i<s.size();i++){            char now=s[i];            if(strmap.find(now)!=strmap.end()){                strmap[now]=INT_MAX;            }else{                strmap[now]=i;            }        }        int min=INT_MAX;        for(unordered_map<char,int>::iterator iter=strmap.begin();iter!=strmap.end();iter++){            min=min>=(iter->second)?(iter->second):min;        }        return min==INT_MAX?-1:min;    }};

执行时间79ms,不是很理想。

思路2
哈希表更适合记录一些离散的值,比如数字,然而note指出,字符串中出现的只会是小写字母,那么完全可以建立一个数组来记录位置。
所以可以把哈希表改为数组,这样时间减少到了42ms,毕竟哈希表的访问速度比数组慢不少。

class Solution {public:    int firstUniqChar(string s) {        int pos[26];        //初始化数组        for(int i=0;i<26;i++){            pos[i]=-1;        }        //更新数组,使得每一个没有重复出现的字符保持着出现的位置        for(int i=0;i<s.size();i++){            int now=s[i]-'a';            pos[now]=pos[now]<0?i:INT_MAX;        }        int min=INT_MAX;        //查询数组,寻找最小值,即最早出现的位置        for(int i=0;i<s.size();i++){            int now=s[i]-'a';            if(pos[now]>=0&&pos[now]<min){                min=pos[now];            }        }        return min==INT_MAX?-1:min;    }};

这个解法带来的问题就是,需要用一个额外的值来记录从未出现过的字符,使得最后查询的时候变得麻烦了一些。
另外,最后查询的时候其实并不需要历遍整个字符串,只需要记录第一个出现的非INT_MAX(没有重复出现),非-1(在字符串中出现过)的位置即可。
思路三
前面两个思路记录的是位置信息,然而最后查询历遍的时候发现位置信息完全可以被变量 i 所取代,所以记录的信息实际上是是否出现过以及是否重复 两点而已。那么换一个思路,记录每个字符出现的次数,可以将这两点合并为出现次数是否为1

class Solution {public:    int firstUniqChar(string s) {        int times[26]={};        int size=s.size();        for(int i=0;i<size;i++){            times[s[i]-'a']++;        }        for(int i=0;i<size;i++){            int now = s[i]-'a';            if(times[now]==1){                return i;            }        }        return -1;    }};

执行时间依然是42ms,但是代码简洁了不少。

思路4
其实这并不是新的思路,但是前面代码写错了,思路2中既然记录了位置,为什么还要历遍字符串呢,历遍一遍记录位置的数组取最小值就好了。

class Solution {public:    int firstUniqChar(string s) {        int pos[26];        //初始化数组        for(int i=0;i<26;i++){            pos[i]=-1;        }        //更新数组,使得每一个没有重复出现的字符保持着出现的位置        for(int i=0;i<s.size();i++){            int now=s[i]-'a';            pos[now]=pos[now]<0?i:INT_MAX;        }        int min=INT_MAX;        //查询数组,寻找最小值,即最早出现的位置        for(int i=0;i<26;i++){            if(pos[i]>=0&&pos[i]<min){                min=pos[i];            }        }        return min==INT_MAX?-1:min;    }};

执行时间39ms,果然比思路3快一点。
思路5
待续

0 0
原创粉丝点击