二. 字符串_回文串的定义_125. 验证回文串

题目描述
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: “A man, a plan, a canal: Panama”
输出: true
解释:“amanaplanacanalpanama” 是回文串
示例 2:

输入: “race a car”
输出: false
解释:“raceacar” 不是回文串

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-palindrome

筛选+判断
这里是回文串的检测
1.这里只需要检查大写字母和小写字母还有数字
2.首先建立while循环,确定两个下标i,j之后,分别从前面和后面找到一个数字和字母
3.检查如果i<j那么判断是否相同,若i>=j,则直接退出

//这里一个向后面遍历,一个向前遍历
//如果没有找到的话,返回-1,找到的话,返回对应的下标
//这里有可能找不到,因为字符串如果没有字符和数字的话,那么就找不到
//因为,他是遍历到字符串的中间就结束了,所以,不会出现一边找到,一边没找到的情况
int findNextA(string &s, int index) {
    int len = s.size();

    for(int i = index; i < len; i++) {
        if(isalnum(s[i])) {  //判断是否是字母或者数字
            return i;
        }
    }

    return -1; //如果没找到,返回-1
}
int findNextB(string &s, int index) {
    int len = s.size();

    for(int i = index; i >= 0; i--) {
        if(isalnum(s[i])) {   //判断是否是字母或者数字
            return i;
        }
    }

    return -1; //如果没找到,返回-1
}
bool isPalindrome(string s) {
    int len = s.size();
    int i = 0, j = len - 1;

    //当i和j相同,或者当i>j时,还没检查出问题的时候,就证明是回文串
    while(i < j) {
        //分别从左边开始找到第一个字母和数字的位置
        //在从右边找到第一个是字母和数字的位置
        i = findNextA(s, i);
        j = findNextB(s, j);

        //如果两个都不等于-1,那么检查是否相等
        if(i != -1 && j != -1) {
            if(s[i] - s[j] == 0) {   //检查是否完全相等
                i++;
                j--;
            } else if(abs(s[i] - s[j]) == 32 && isalpha(s[i]) && isalpha(s[j])) {  //这里如果是字母的话,那么排除大小写
                i++;
                j--;
            } else {
                return false;
            }
        } else if(i == -1 && j == -1) {   // 如果都等于-1,那说明这个字符串没有字母
            return true;
        }
    }

    return true;
}
/*
i,j的下标一共有这几种情况
1.有字母 { ①有一个字母,i==j,②有两个字母那么i!=j}
2.无字母 {i=-1,j=-1}
这里基本的方法是将原有string中,字符和数字的将其赋值到另一数组中,复制到另一数组中之后,
按照i,j两个指针找到对应的元素比较是否相同即可,当i==j时停止。
或者将字符串逆置,比较这两个字符串是否相等即可。
回文串的特点是,他的逆置还是他自己。*/
bool isPalindrome(string s) {
    string temp;

    //将数字和字符添加到temp中
    //tolower函数的作用将大写转换成小写,而非字符不做处理
    //这个函数可以通过ascii判断是否为大写,若为大写那么在将其转为小写
    //这样排除了大小写的问题

    //for(int i = 0; i < s.size(); i++) {
    //    if(isalnum(s[i])) {
     //       temp += tolower(s[i]);
      //  }
   // }

    //这里不需要下标for循环可以写成这样
    for(char c : s) {
        if(isalnum(c)) {
            temp += tolower(c);
        }
    }

    string rev_temp(temp.rbegin(), temp.rend());   //以temp字符串逆序的方式创建rev_temp
    return rev_temp == temp;
}

时间复杂度是O(|s|),空间复杂度是O(|s|)

bool isPalindrome(string s) {
    string temp;

    for(char c : s) {
        if(isalnum(c)) {
            temp += tolower(c);
        }
    }

    for(int i = 0, j = temp.size() - 1; i < j; i++, j--) {
        if(temp[i] != temp[j]) {
            return false;
        }
    }

    return true;
}

在原字符串上直接判断
先找到对应的字母或者数字,在判断是否相同

bool isPalindrome(string s) {
    int i = 0, j = s.size() - 1;

    while(i < j) {
        //这里条件换成i<j也是可以的,当然,当有字母的时候没差别,没字母的时候i<j比较的次数,稍微少几次。
        while(!isalnum(s[i]) && i < s.size()) { //当没有字母的时候,需要检查i的合法性
            i++;
        }

        while(!isalnum(s[j]) && j > 0) {
            j--;
        }

        if(i < j) {  //如果i<j,那么一定是找到了字母
            if(tolower(s[i]) == tolower(s[j])) {   //下标合法,那么比较
                i++;
                j--;
            } else { //如果不相等的话,那么返回false
                return false;
            }
        }//其他情况下,有字母情况下,那么之前对比的都相等,已经到停止条件了

        //没有字母的情况下,那么肯定就相等,也到了停止条件了,那么终止
    }

    return true;
}


int main() {
    bool flag = isPalindrome("0P");
    cout << flag << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值