万人千题计划-26

今日题目共八道

向大家推荐一下我们的社区:万人千题
同时向大家推荐一下我们社区几位大佬的主页
英雄哥
磊哥
解题者大佬

第一题:回文排列.

思路:只有当字符个数奇数个的情况最多有一个时,才会形成回文字符串

class Solution {
public:
    bool canPermutePalindrome(string s) {
        int res = 0;
        unordered_map<char, int> map;
        for(auto &c : s) {
            map[c]++;
        }
        for(auto &c : map) {
            if(c.second&1) res++;
        }
        return res <= 1;
    }
};

第二题:有效的回文.

思路:在左指针比右指针小的前提下,比较左右指针所指的值是否相等,同时在比较的时候使用isalnum()和tolower()函数。为了不让字符串越界,特别在循环里面再次添加了left<right条件

isalnum()函数:判断一个字符是否是字母或者十进制数字,若为字母和数字则返回真,否则返回否

tolower()函数:把字符转换成小写字母,非字母字符不做出处理。

方法一:双指针

class Solution {
public:
    bool isPalindrome(string s) {
        //双指针
        int left = 0, right = s.size()-1;
        while(left < right) {
            while(left < right && !isalnum(s[left])) {
                ++left;
            }
            while(left < right && !isalnum(s[right])) {
                --right;
            }
            if(tolower(s[left]) != tolower(s[right])) {
                return false;
            }
            ++left;
            --right;
        }
        return true;
    }
};

方法二:使用库函数
思路:新建一个字符串与字符串一相等,使用reverse函数反转字符,与之比较

class Solution {
public:
    bool isPalindrome(string s) {
        string str1;
        for(char &i : s) {
            if(isalnum(i)) {
                str1 += tolower(i);
            }
        }
        string str2=str1;
        reverse(str1.begin(), str1.end());
        return str1 == str2;
    }
};

第三题:验证回文串.与第二题相同,我就不赘述了

第四题:最长回文串.

思路:使用上词学到的哈希映射来解决问题,然后利用
if判断条件(map[c - ‘A’] & 1) 是否为 0
来判断该字母个数达到偶数,若为偶数,则res+2

class Solution {
public:
    int longestPalindrome(string s) {
        int res = 0;
        unordered_map<char, int>map;
        for(char &c : s) {
            map[c - 'A']++;
            if((map[c - 'A'] & 1) == 0) {
                res += 2;
            }
        }
        return res == s.size() ? res : res+1;
    }
};

第五题:最多删除一个字符得到回文.

思路:左右双指针,比较左右指针所指的值,直到左右指针交叉重合

class Solution {
public:
    bool validPalindrome(string s) {
        int left = 0, right = s.size()-1;
        while(left<right && s[left] == s[right]) {
            ++left;
            --right;
        }
        return Palindrom(s, left+1, right) || Palindrom(s, left, right-1);
    }

    bool Palindrom(const string& s, int left, int right) {
        while(left < right && s[left] == s[right]) {
            ++left;
            --right;
        }
        return left >= right;
    }
};

第六题:验证回文字符串Ⅱ.

与第五题相同

第七题:删除回文子序列.

思路:主要是题目有点绕,删除的是回文子序列,不是子字符串
所以一共有三种情况:
空字符返回0,回文返回1,否则一次全部删a,一次全部删b,返回2

class Solution {
public:
    int removePalindromeSub(string s) {
        if(s.size() == 0) return 0;
        for(int left=0, right=s.size()-1; left<right; left++, right--) {
            if(s[left] != s[right]) {
                return 2;
            }
        }
        return 1;
    }
};

第八题:最短回文串.

思路:就是将字符串正序和逆序转换为base进制的数,然后比较两个数取模后是否相等,如果相等,表示两个字符串相等。
KMP我一时半会是搞不定了,但如果是哈希的话,还是可以接受这种思路

class Solution {
public:
    string shortestPalindrome(string s) {
        int n = s.size();
        int base = 131, mod = 1000000007;
        int left = 0, right = 0, mul = 1;
        int best = -1;
        for (int i = 0; i < n; ++i) {
            left = ((long long)left * base + s[i]) % mod;
            right = (right + (long long)mul * s[i]) % mod;
            if (left == right) {
                best = i;
            }
            mul = (long long)mul * base % mod;
        }
        string add = (best == n - 1 ? "" : s.substr(best + 1, n));
        reverse(add.begin(), add.end());
        return add + s;
    }
};

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>