leetcode 5 最长回文子串
- 暴力解法,每个字母向两边扩散计算,复杂度O(n^2)
func longestPalindrome(s string) string {
//两个for循环
res:=""
if len(s)==0{
return res
}
//没有则返回第一个
start,Len:=0,1
for i:=0;i<len(s);i++{
l,r:=i,i
for l>=0&&r<len(s)&&s[l]==s[r]{
l--
r++
}
if r-l+1-2>Len{
start = l+1
Len = r-l-1
}
l,r = i,i+1
for l>=0&&r<len(s)&&s[l]==s[r]{
l--
r++
}
if r-l+1-2>Len{
start = l+1
Len = r-l-1
}
}
tmp:=[]byte(s)
return string(tmp[start:start+Len])
}
- 优化解法(马拉车) 复杂度O(n)
马拉车参考教程
func longestPalindrome(s string) string {
//特殊判断
if len(s)<1{
return s
}
res:=s
start,Len:=0,0
size:=2*len(s)+1
//右侧最远和对应的中心
maxRight,center:=0,0
//获取处理之后的字符串
s=getstr(s)
//p记录对应的长度
p:=make([]int,size)
for i:=0;i<size;i++{
mirror:=2*center-i
if p[i]<maxRight-i{ //复用前面计算过的
p[i] = min(p[mirror],maxRight-i)
}
left,right:=i-(p[i]+1),i+(p[i]+1)
for left>=0&&right<size&&s[left]==s[right]{
p[i]++
left--
right++
}
//更新center和maxRight
if i+p[i]>maxRight{
maxRight = i+p[i]
center = i
}
//更新距离
if p[i]>Len{
Len = p[i]
start = (i-Len)/2
}
}
//从原来字符串截取
tmp:=[]byte(res)
return string(tmp[start:start+Len])
}
//增加间隔字符串
func getstr(str string)string{
res:=[]byte{'#'}
for i:=0;i<len(str);i++{
res = append(res,str[i])
res = append(res,'#')
}
return string(res)
}
func min(x,y int)int{
if x>y{
return y
}else{
return x
}
}
leetcode387 字符串中第一个唯一字符
计数数组记录26个字母的数量
func firstUniqChar(s string) int {
//记数数组
flag:=make([]int,26)
str:=[]rune(s)
for i:=0;i<len(str);i++{
flag[s[i]-'a']++
}
//找到第一个出现一次字符的位置
for i:=0;i<len(str);i++{
if flag[s[i]-'a']==1{
return i
}
}
return -1
}
8 实现atoi
注意可能出现的边界情况 -+123 纯空串“ ”
func myAtoi(s string) int {
max:=math.MaxInt32
min:=math.MinInt32
str:=[]rune(s)
//空返回0
if len(str)==0{
return 0
}
res:=0
flag:=true
i:=0
for ;i<len(str);i++{
if str[i]==' '{
continue
}else{
break
}
}
//前面全为空格
if i>=len(str) {
return 0
}
//判断正负号 可能出现-+情况
if str[i]=='-'{
flag = false
i++
}else if str[i]=='+'{
i++
}
for ;i<len(str);i++{
if str[i]>='0'&&str[i]<='9'{
if flag{
res = res*10+int(str[i]-'0')
if res>max{
res = max
break
}
}else{
res = res*10-int(str[i]-'0')
if res<min{
res = min
break
}
}
}else{
break
}
}
return res
}
451根据字符串出现频率进行排序
桶排序
c++ O(n) O(a)//a为出现次数最多的字符数
string frequencySort(string s) {
if(s.size()==0)return "";
//桶排序
unordered_map<char,int>hash;
int Maxlen = 0;
//放字符 保留最大值
for(int i=0;i<s.size();i++)
{
hash[s[i]]++;
Maxlen = max(Maxlen,hash[s[i]]);
}
//放ascill值 容量为出现最多次数+1而不是hash.size()
vector<vector<int>>buckets(Maxlen+1);
for(unordered_map<char,int>::iterator iter=hash.begin();iter!=hash.end();iter++)
{
buckets[iter->second].push_back(iter->first);//上面使用最大次数的原因,不用会溢出
}
//输出字符串
string res;
for(int i=Maxlen;i>=1;i--)
{
for(int j=0;j<buckets[i].size();j++)
{
//放置多次
for(int z = 0;z<i;z++)
{
res.push_back(buckets[i][j]);
}
}
}
return res;
}