Leetcode笔记之字符串

string s="";//初始化

一.字符串简单题型

8.字符串转整数 (atoi)

1.定义 i=0;while 跳过空格
2.if 跳过+/-,确定符号sign;并且符号之后必须紧跟数字,否则返回0
3.溢出判断:如果当前res> INT_MAX / 10 或者res == INT_MAX / 10 && str[i] - ‘0’ > 7:sign为1返回INT_MAX,否则返回 INT_MIN。
4.res累积:res = 10 * res + (str[i++] - ‘0’);

int myAtoi(const char* str) {
    if(!str)
        return 0;
    int sign = 1, res = 0, i = 0;
    while (str[i] == ' ')  i++; //1.跳过空格
    if (str[i] == '-' || str[i] == '+') //2.+/-跳过,确定符号
    {
        if (str[i] == '-' ) sign=-1;
        ++i;
    }
    while (str[i] >= '0' && str[i] <= '9')//3.符号之后必须紧跟数字,否则返回0
    {
        if (res >  INT_MAX / 10 || (res == INT_MAX / 10 && str[i] - '0' > 7)) {//4.溢出判断
            if (sign == 1) 
                return INT_MAX;
            else 
                return INT_MIN;
        }
        res  = 10 * res + (str[i++] - '0');//5.计算
    }
    return res * sign;
}

28.实现strStr()

给定一个 S1 字符串和一个s2 字符串,在 S1字符串中找出s2字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
1.计算字符串长度的函数:int str_length(const char* str);
2.KMP算法的next计算函数:void Next(char* str,int* next,const int n);
3.if(k==len2) return i-lens2+1;

int str_length(const char* str)
{
    if(!str)
        return 0;
    int i=0;
    while(*str++ != '\0') ++i;
    return i;  
}
void Next(char* str,int* next,const int n)
{
    if(!str)
        return;
    next[0]=0;
    for(int i=1,k=0;i<n;++i)
    {
        while(k>0 && str[i]!=str[k])
            k=next[k-1];
        if(str[i]==str[k])
            ++k;
        next[i]=k;
    }
}
int strStr(char* haystack, char* needle) {
    if(!needle || !haystack)
        return -1;
    if(*needle=='\0')
        return 0;
    int len1=str_length(haystack);
    int len2=str_length(needle);
    int* next=(int*)malloc(len2*sizeof(int));
    Next(needle,next,len2);
    for(int i=0,k=0;i<len1;++i)
    {
        while(k>0 && haystack[i]!=needle[k])
            k=next[k-1];
        if(haystack[i]==needle[k])
            ++k;
        if(k==len2){
            free(next);
            return i-len2+1;
        }     
    }
    return -1;
}

3. 无重复字符的最长子串

1.申请一个hash表,保存当前字符的上一次出现的位置,变量pre记录截止到上一个字符的最长无重复字串的长度,申请一个数组dp[n],保存截止到当前位置的最长无重复字串的长度。
2.for循环遍历字符串,如果当前字符在hash中:
如果上一次出现的位置在i-pre和i之间,即M[s[i]] >= i-pre,则截止到当前位置的最长无重复字串长度为上次出现位置和本次为止的差:dp[i]=i-M[s[i]];;否则长度+1:dp[i]=++pre;
3.如果当前字符不在hash中,长度直接+1:dp[i]=++pre;

14.最长公共前缀

1.每次比较一个字符(在strs[0]中的位置为index),然后把这个字符和strs中其余字符串的对应index处的字符比较,相等则prefix加上这个字符然后继续;
2.否则返回当前prefix(加字符之前)。注意idx >= strs[i].size()时表示即将越界,直接返回当前prefix

string longestCommonPrefix(vector<string>& strs) {
    string prefix = "";
    int n=strs.size();
    if (n<=0)
        return prefix;
    //prefix每次多一个strs[0]中的字符:d,do,dog;对于strs[0]中的每一个字符的下标idx
    for(int idx=0; idx<strs[0].size(); prefix+=strs[0][idx], idx++)
        for(int i=0; i<n; i++)//对于strs中的每一个字符串
            //如果idx不小于当前字符串strs[i]中字符个数 或者 strs[i]中当前字符与strs[0]中当前对应字符串不一样,则返回prefix
            if(idx >= strs[i].size() ||(i > 0 && strs[i][idx] != strs[0][idx]))
                return prefix;
    return prefix;
}

17.电话号码的字母组合

res.push_back(“”)初始化
1.申请一个数组,for循环对于digits中的每一个数字,得到其索引用来访问v,判断合法输入,得到v中对应的字符串vi(const string& vi = v[num]), 如果0和1位置为空字符串则放弃本轮;

static const vector<string> v = {"", "", "abc", "def", "ghi",\
 "jkl", "mno", "pqrs", "tuv", "wxyz"};//1.对应0~9

2.每次迭代的结果保存在tmp,可以发现,随着得到每一轮的结果,res中字符串组合的个数是不断增多的,最后要交换res和tmp的值从而更新res;

vector<string> tmp;
for(int j = 0; j < vi.size(); ++j)//4.1 对于vi中的每个字符
    for(int k = 0 ; k < res.size() ; ++k)//4.2 对于res中的每个字符串
        tmp.push_back(res[k] + vi[j]);//4.3 res中的每个字符串+vi中的每个字符
swap(res,tmp);//5.交换res和tmp

20. 有效的括号

1.for(auto i : s),对于s中的每一个括号,如果st为空,直接入栈;
2.如果st不为空,即将插入的括号和st.top()的括号恰好匹配,则弹出栈顶;否则入栈。

bool isValid(string s) {
    stack<char> st;
    for(auto i : s)
    {
        if(!st.empty())
        {
            //如果即将插入的括号和st.top()的括号恰好匹配,则弹出栈顶,否则入栈
            if((st.top() == '{' && i == '}') || (st.top() == '[' && i == ']') || (st.top() == '(' && i == ')') )       
                st.pop();
            else                                    
                st.push(i);
        }
        else//st为空,直接入栈                                        
            st.push(i);
    }
    return st.empty();
}

22.括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
1.addingpar(vector< string > &v, string str, int n, int m);
//res, 初始化str(字符串这为了+,总是初始化为”“), 当前可添加的左括号个数,当前可添加的右括号个数;
2.1 m,n都为0,表示不可再添加
if(n==0 && m==0) {v.push_back(str);,return;}
2.2 添加左括号,同时可添加的左括号个数-1,右括号个数相应+1
addingpar(v, str+”(“, n-1, m+1);
2.3 添加右括号,同时可添加的左括号个数不变,右括号个数相应-1
addingpar(v, str+”)”, n, m-1);

vector<string> generateParenthesis(int n) {
    vector<string> res;
    addingpar(res, "", n, 0);//
    return res;
}
void addingpar(vector<string> &v, string str, int n, int m){
    if(n==0 && m==0) //m,n都为0,表示不可再添加
    {
        v.push_back(str);
        return;
    }
    if(n > 0)
        addingpar(v, str+"(", n-1, m+1); //添加左括号,同时可添加的左括号个数-1,,右括号个数相应+1
    if(m > 0)
        addingpar(v, str+")", n, m-1); //添加右括号,同时可添加的左括号个数不变,,右括号个数相应-1

}

58.最后一个单词的长度

和求第一个单词的长度解法一样
法一:从后往前遍历,去掉后面的空格,开始计数就可以了,直到又遇到了空格,返回res即可。和找第一个单词的长度一样的方法
法二:先反转s,然后求第一个单词的长度(从第一个非空格开始计数,++res;,直到下一个空格停止遍历,返回res即可)

int len = 0, i = s.size() - 1;
while (i >= 0 && s[i] == ' ') i--;
while (i >= 0 && s[i] != ' ') { len++; i--; }
return len;

猜你喜欢

转载自blog.csdn.net/qiangzhenyi1207/article/details/80257511