大家好,我是开车的阿Q,自动驾驶的时代已经到来,没时间解释了,快和阿Q一起上车。作为自动驾驶系统工程师,必须要有最好的C++基础,让我们来一起刷题吧。

题目考察的知识点

字符串处理,回文字符串,双指针。

题目解答方法的文字分析

我们需要判断给定的密码是否满足特定条件:

  1. 密码中至多包含 k 个不同的字符。
  2. 可以删除其中一个字符后,得到一个回文字符串。

思路:

  1. 首先,我们要统计密码中不同字符的个数。可以使用一个集合(set)来记录出现过的字符,因为集合的特性保证不会重复计数。
  2. 如果密码中不同字符的个数小于等于 k,那么满足第一个条件。
  3. 然后,我们要判断是否可以删除一个字符得到回文字符串。为了实现这一点,我们可以使用双指针,一个从字符串的开头开始,另一个从结尾开始,依次判断对应字符是否相等,直到两个指针相遇或交错为止。
  4. 在这个过程中,如果发现两个指针指向的字符不相等,我们可以删除其中一个字符,然后继续判断是否是回文字符串。
  5. 如果可以删除一个字符得到回文字符串,则满足第二个条件,返回 true,否则返回 false。

举个例子:假设 password = "abca",k = 1。

  1. 统计不同字符的个数:'a', 'b', 'c',不同字符个数为 3,小于等于 k,满足第一个条件。
  2. 使用双指针判断是否可以删除字符得到回文字符串:i 指向 'a',j 指向 'a',字符相等,继续判断。i 指向 'b',j 指向 'a',字符不相等,可以删除其中一个字符,假设删除 'b',然后判断 'a' 和 'a' 是否相等,相等,返回 true。

本题解析所用的编程语言

C++

完整且正确的编程代码

class Solution {
  public:
    bool isValidPalindrome(string password, int k) {
        // 统计不同字符的个数
        unordered_set<char> charSet;
        for (char c : password) {
            charSet.insert(c);
        }

        // 判断是否满足第一个条件:不同字符个数不超过 k
        if (charSet.size() > k) {
            return false;
        }

        // 使用双指针判断是否可以删除字符得到回文字符串
        int i = 0, j = password.size() - 1;
        int num = 1;
        while (i < j) {
            if (password[i] != password[j]) {
                // 可以删除其中一个字符,继续判断
                num--;
                if (num < 0) {
                    return false; // 已经删除了一个字符,仍然没有得到回文字符串,返回 false
                }
                // 删除左侧字符,i 向右移动;删除右侧字符,j 向左移动
                if (password[i + 1] == password[j]) {
                    i++;
                } else if (password[i] == password[j - 1]) {
                    j--;
                } else {
                    return false; // 不能通过删除一个字符得到回文字符串,返回 false
                }
            } else {
                i++;
                j--;
            }
        }

        return true;
    }
};

您的关注、点赞、收藏就是我创作的动力,三连支持阿Q!