回文字符串是指一个字符串从前往后与从后往前读获得同样的结果,比如abcdcba
。下面我们来总结一下各种方法判断一个字符串是否为回文字符串。
- for循环法
function isPalindRome(input){
if(typeof input !== 'string') return false;
let len = input.length;
let str = '';
for(let i=len-1; i>=0; i--){
str += input[i];
}
return str === input;
}
- charAt()
function isPalindRome1(input){
if(typeof input !== 'string') return false;
let len = input.length;
for(let i=0; i<len; i++){
if(input.charAt(i) !== input.charAt(len-1-i)){
return false;
}
}
return true;
}
- 借助数组法
function isPalindRome2(input){
if(typeof input !== 'string') return false;
return input.split('').reverse().join('') === input;
}
- 使用栈
/*使用栈stack类的实现*/
function stack() {
this.dataStore = [];//保存栈内元素,初始化为一个空数组
this.top = 0;//栈顶位置,初始化为0
this.push = push;//入栈
this.pop = pop;//出栈
this.peek = peek;//查看栈顶元素
this.clear = clear;//清空栈
this.length = length;//栈内存放元素的个数
}
function push(element){
this.dataStore[this.top++] = element;
}
function pop(){
return this.dataStore[--this.top];
}
function peek(){
return this.dataStore[this.top-1];
}
function clear(){
this.top = 0;
}
function length(){
return this.top;
}
/*使用栈判断给定字符串是否是回文的算法*/
function isPalindRome3(word){
var s = new stack();
for(var i = 0;i < word.length;i++){
s.push(word[i]);
}
var rword = "";
while(s.length() > 0){
rword += s.pop();
}
if(word == rword){
return true;
}else{
return false;
}
}
- 使用单链表(提供思路)
最近在学习数据结构与算法时,有一个使用单链表来存储字符串,判断这个字符串是否是回文字符串的问题,在这里主要将一下思路:
由于回文串最重要的就是对称,那么最重要的问题就是找到那个中心,我们可以通过快慢指针的策略。慢指针每次前进一步,快指针每次前进两步。当快指针到达链表末端的时候,慢指针刚好到达中心,慢指针在过来的这趟路上还做了一件事,他把走过的节点反向了,在中心点再开辟一个新的指针用于往回走,而慢指针继续向前,当慢指针扫完整个链表,就可以判断这是回文串,否则就提前退出。
总的来说时间复杂度按慢指针遍历一遍来算是O(n),空间复杂度因为只开辟了3个额外的辅助,所以是o(1)
对于第五种方法,有什么疑问的话,可留言一同探讨。
这里贴一下C++版本的实现代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode prev = null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
ListNode next = slow.next;
slow.next = prev;
prev = slow;
slow = next;
}
if (fast != null) {
slow = slow.next;
}
while (slow != null) {
if (slow.val != prev.val) {
return false;
}
slow = slow.next;
prev = prev.next;
}
return true;
}
}
参考文章:https://github.com/andavid/leetcode-java/blob/master/note/234/README.md