声明:
作者不是什么大佬,只是想写写算法,提高一下自己的内功。所以代码可能会非常凌乱,(大佬们就当个笑话看就可以了),但我会认真注释。
最后如果有路过的大佬,希望可以留下你们的建议和看法,谢谢!
125. 验证回文串
一、原题链接
二、题目介绍
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
三、测试用例
1.示例
输入: “A man, a plan, a canal: Panama”
输出: true
2.示例
输入: “race a car”
输出: false
四、思路解析
在面对判断回文串的情况我一般会使用快慢指针的方式进行解答。
通过快慢指针快速定位到中点,之后从两端出发依此判断。
注意:这道题型简单会有更快速的方式,但是如果固定使用快慢指针解题,该题可以当作快慢指针的入门练习题
五、代码
class Solution {
public boolean isPalindrome(String s) {
// 将字符串刷新到自定义链表
int cha = 32;
LinkedChar linkedChar = new LinkedChar();
for (char c : s.toCharArray()) {
if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z') {
linkedChar.push(c);
} else if (c >= 'A' && c <= 'Z') {
int temp = c + 32;
linkedChar.push((char) temp);
}
}
// 判断简单的情况,直接返回
switch (linkedChar.size){
case 0: return true;
case 1: return true;
case 2: return linkedChar.head.value == linkedChar.head.next.value;
case 3: return linkedChar.head.value == linkedChar.head.next.next.value;
}
// 根据快慢指针获取中间元素
LinkedElem fast = linkedChar.head;
LinkedElem slow = linkedChar.head;
while (fast.next!=null && fast.next.next !=null) {
slow = slow.next;
fast = fast.next.next;
}
// 根据最后一次指针停留位置和链表长度,设置快慢指针的往左右遍历的位置
if(linkedChar.size%2==0){
fast = slow.next;
}else {
fast = slow.next;
slow = slow.pre;
}
// 开始遍历
while (fast!=null){
if(fast.value != slow.value){
// 有一次不一样就返回false
return false;
}else {
fast = fast.next;
slow = slow.pre;
}
}
// 全部通过返回true
return true;
}
}
// 自定义Char类型的链表结构
class LinkedChar {
// 当前链表头指针
LinkedElem head;
// 当前链表尾指针
LinkedElem last;
// 当前链表长度
int size = 0;
// 链表是否为空
boolean isEmpty() {
return size == 0;
}
// 链表添加
void push(char c) {
// 将要添加的字符封装为链表元素
LinkedElem elem = new LinkedElem();
elem.value = c;
// 分情况添加 此时为空时添加元素
if (size == 0) {
// 更新链表的头尾指针
this.head = elem;
this.last = elem;
elem.next = null;
elem.pre = null;
} else {
// 设定当前元素的前一个元素为尾部
elem.pre = this.last;
// 将当前元素放到尾部
this.last.next = elem;
// 跟新尾部的指针
this.last = elem;
}
// 长度加1
size++;
}
}
// 链表元素
class LinkedElem {
// 前指针
LinkedElem pre;
// 后指针
LinkedElem next;
// 当前元素
char value;
}