LeetCode刷题(十三)-----字符串-------easy部分(Java、C++)

125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
示例 2:
输入: “race a car”
输出: false
思路一:
解法一:

class Solution {
public:
	bool isPalindrome(string s) {
		string s1;
		for (int i = 0; i < s.length(); i++)
		{
			if (s[i] == ' ')
			{
				i = s.find_first_not_of(' ',i);//从第i位置开始找第一个不为空格的位置
                if(i==-1) 
                    break;
			}
			if ((s[i] >= 'A'&&s[i] <= 'Z') || (s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= '0'&&s[i] <= '9'))//是数字或者字母
			{
				if (s[i] >= 'A'&&s[i] <= 'Z')//大写转小写
				{
					s[i] = (s[i] + 32);
					s1 = s1 + s[i];
				}
				else
				{
					s1 = s1 + s[i];
				}
			}
			else continue;
		}
		string ress1 = s1;
		std::reverse(ress1.begin(), ress1.end());//回转字符串
		if (ress1 == s1)若相等
			return true;
		else return false;
	}
};

该方法在字符串过大时,反转过程消耗过大的内存,故该方法在最后一个测试用例过不去。

解法2:双指针法:
在这里插入图片描述
isalnum(char c):判断字符变量c是否为字母或数字,若是则返回非零,否则返回零。
tolower(char c):把字母字符转换成小写,非字母字符不做出处理。

作者:chenlele
链接:https://leetcode-cn.com/problems/valid-palindrome/solution/yan-zheng-hui-wen-chuan-by-gpe3dbjds1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我的:

class Solution {
public:
    bool isPalindrome(string s) 
    {
        if(s.size()<=1)
        {
            return true;
        }
        int i = 0;
        int j = s.size() - 1;
        while(i < j)
        {
            while(i < j&&!isalnum(s[i]))
            {
                i++;
            }
            while(i < j&&!isalnum(s[j]))
            {
                j--;
            }
            if(tolower(s[i++])!=tolower(s[j--]))
            {
                return false;
            }
        }
        return true;    
    }
};

20. 有效的括号

 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
 有效字符串需满足:
 左括号必须用相同类型的右括号闭合。
 左括号必须以正确的顺序闭合。
 注意空字符串可被认为是有效字符串。

示例 1:
输入: “()”
输出: true
示例 2:
输入: “()[]{}”
输出: true
示例 3:
输入: “(]”
输出: false
示例 4:
输入: “([)]”
输出: false
示例 5:
输入: “{[]}”
输出: true

想法一:
具体的思路就跟主流的思路一样,使用栈。
一.判断前括号还是后括号
1.前括号,压入。
2.后括号,判断是否可以pop和是否有匹配的前括号
二.此时循环结束,判断栈里是否还有残留
当然,中间的if对比还有可以优化的地方(可以有效减少对比的次数)
在这里插入图片描述
作者:haru-8
链接:https://leetcode-cn.com/problems/valid-parentheses/solution/cjie-fa-yong-shi-0ms-by-haru-8/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

ss.push(12);// 添加元素
ss.top();// 读取栈顶元素
ss.pop();// 弹出栈顶元素

我的:

class Solution {
public:
    bool isValid(string s) 
    { 
        if(s==" ")
        {
            return true;
        }   
        if(s.size()%2 != 0)
        {
            return false;
        }
        stack<char> ss;
        for(auto i : s)
        {
            if(i=='{'||i=='('||i=='[')
            {
                ss.push(i);
            }
            else
            {
                if(ss.size() == 0 && (i == ']'||i == '}'||i == ')'))
                {
                    return false;
                }
                else if((i == '}' && ss.top()!='{')||(i == ']' && ss.top()!='[')||(i == ')' && ss.top()!='('))
                {
                    return false;
                }
                else
                {
                    ss.pop();
                }
            }
        }
        if(ss.size()!=0)
        {
            return false;
        }
        return true;
    }
};

28. 实现 strStr()

实现strStr()函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

示例 1:
输入: haystack = “hello”, needle = “ll”
输出: 2
示例 2:
输入: haystack = “aaaaa”, needle = “bba”
输出: -1
说明:
当needle是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当needle是空字符串时我们应当返回0。这与C语言的strstr()以及Java的indexOf()定义相符。
想法一:
库函数解法:
在这里插入图片描述
BF算法 暴力破解:
时间复杂度O(M*N)
在这里插入图片描述
KMP解法:
时间复杂度O(M+N)

class Solution {
public:
    vector<int> getnext(string str)
        {
            int len=str.size();
            vector<int> next;
            next.push_back(-1);//next数组初值为-1
            int j=0,k=-1;
            while(j<len-1)
            {
                if(k==-1||str[j]==str[k])//str[j]后缀 str[k]前缀
                {
                    j++;
                    k++;
                    next.push_back(k);
                }
                else
                {
                    k=next[k];
                }
            }
            return next;
        }
    int strStr(string haystack, string needle) {
        if(needle.empty())
            return 0;
        
        int i=0;//源串
        int j=0;//子串
        int len1=haystack.size();
        int len2=needle.size();
        vector<int> next;
        next=getnext(needle);
        while((i<len1)&&(j<len2))
        {
            if((j==-1)||(haystack[i]==needle[j]))
            {
                i++;
                j++;
            }
            else
            {
                j=next[j];//获取下一次匹配的位置
            }
        }
        if(j==len2)
            return i-j;
        
        return -1;
    }
};

//KMP 的 next 数组可以进行优化,当字符失配时,回到相同字符无意义,应继续递归
在这里插入图片描述
BM算法:
时间复杂度最差和KMP一样 最佳是O(n)

class Solution {
public:
    void get_bmB(string& T,vector<int>& bmB)//坏字符
    {
        int tlen=T.size();
        for(int i=0;i<256;i++)//不匹配直接移动子串
        {
            bmB.push_back(tlen);
        }
        for(int i=0;i<tlen-1;i++)//靠右原则
        {
            bmB[T[i]]=tlen-i-1;
        }
    }
    
    void get_suff(string& T,vector<int>& suff)
    {
        int tlen=T.size();
        int k;
        for(int i=tlen-2;i>=0;i--)
        {
            k=i;
            while(k>=0&&T[k]==T[tlen-1-i+k])
                k--;
            suff[i]=i-k;
        }
    }
    
    void get_bmG(string& T,vector<int>& bmG)//好后缀
    {
        int i,j;
        int tlen=T.size();
        vector<int> suff(tlen+1,0);
        get_suff(T,suff);//suff存储子串的最长匹配长度
        //初始化 当没有好后缀也没有公共前缀时
        for(i=0;i<tlen;i++)
            bmG[i]=tlen;
        //没有好后缀 有公共前缀 调用suff 但是要右移一位 类似KMP里的next数组
        for(i=tlen-1;i>=0;i--)
            if(suff[i]==i+1)
                for(j=0;j<tlen-1;j++)
                    if(bmG[j]==tlen)//保证每个位置不会重复修改
                        bmG[j]=tlen-1-i;
        //有好后缀 有公共前缀
        for(i=0;i<tlen-1;i++)
            bmG[tlen-1-suff[i]]=tlen-1-i;//移动距离
    }
    
    int strStr(string haystack, string needle) {
        
        int i=0;
        int j=0;
        int tlen=needle.size();
        int slen=haystack.size();
        
        vector<int> bmG(tlen,0);
        vector<int> bmB;
        get_bmB(needle,bmB);
        get_bmG(needle,bmG);
        
        while(i<=slen-tlen)
        {
            for(j=tlen-1;j>-1&&haystack[i+j]==needle[j];j--);
            if(j==(-1))
                return i;
            i+=max(bmG[j],bmB[haystack[i+j]]-(tlen-1-j));
        }
        return -1;
    }
};

Sunday 时间复杂度:
最坏为O(M*N) 平均复杂度为O(N)

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.empty())
            return 0;
        int slen=haystack.size();
        int tlen=needle.size();
        int i=0,j=0;//i指向源串首位 j指向子串首位
        int k;
        int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
        
        for(;i<slen;)
        {
            if(haystack[i]!=needle[j])
            {
                for(k=tlen-1;k>=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
                {
                    if(needle[k]==haystack[m])
                        break;
                }
                i=m-k;//i为下一次匹配源串开始首位 Sunday算法核心:最大限度跳过相同元素
                j=0;//j依然为子串首位
                m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
                if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
                    return -1;
            }
            else
            {
                if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
                    return i-j;
                i++;
                j++;
            }
        }
        return -1;//当超过源串长度时 
    }
};

作者:2227
链接:https://leetcode-cn.com/problems/implement-strstr/solution/c5chong-jie-fa-ku-han-shu-bfkmpbmsunday-by-2227/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我的:

class Solution {
public:
    int strStr(string haystack, string needle) 
    { 
        if(needle.empty())
        {
            return 0;
        }     
        int pos = haystack.find(needle);
        return pos;
    }
};

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。

示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:所有输入只包含小写字母 a-z 。
思路一:
分析:
选择其中一个字符串作为对照标准,与后面的比较获得最长公共前缀res,再用res继续与后面的字符串比较,最后获得最终结果。
实现代码:
在这里插入图片描述
我的:

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        if(strs.empty())
        {
            return "";
        }
        string res = strs[0];
        for (int i= 1;i<strs.size();i++)
        {
            for(int j=0;j<res.size();j++)
            {
                if(strs[i][j] == res[j])
                {
                    continue;
                }
                else
                {
                    res.erase(j);
                    break;
                }
            }
        }
        return res;    
    }
};

发布了47 篇原创文章 · 获赞 21 · 访问量 7238

猜你喜欢

转载自blog.csdn.net/qq_18315295/article/details/103557005
今日推荐