8.8 KiB
title | localeTitle |
---|---|
Palindrome Checker | 回文检查 |
如果卡住,请记得使用**Read-Search-Ask
** 。尝试配对程序并编写自己的代码
问题说明:
我们解决这个问题的目的是整理传入的字符串,并检查它是否实际上是回文。
- 如果你不确定回文是什么,那么它就是一个单词或短语,当反向拼写相同的东西向前或向后。一个简单的例子是
mom
,当你翻转字母时,它会拼出相同的东西!回文的另一个例子是race car
。当我们取出任何不是角色的东西时,它变成同样拼写向前或向后的racecar
!
一旦我们确定它是否是回文,我们想根据我们的发现返回true
或false
。
相关链接
提示:1
正则表达式RegEx
可用于从字符串中删除不需要的字符。
现在尝试解决问题
提示:2
Array.prototype.split
和Array.prototype.join
方法可以在这里使用。 For
和while
循环是另一种选择,或者为什么不map
!
现在尝试解决问题
提示:3
String.prototype.toLowerCase
可用于使字符串小写。
现在尝试解决问题
扰流警报!
提前解决!
基本代码解决方案
function palindrome(str) {
return str.replace(/[\W_]/g, '').toLowerCase() ===
str.replace(/[\W_]/g, '').toLowerCase().split('').reverse().join('');
}
代码说明:
-
我们首先使用正则表达式将任何空格或非字母数字字符替换为
null
(或null
),这实质上将它们从字符串中删除。 -
接下来我们_连锁_
.toLowerCase()
以消除任何大写字母,因为A
是不同的字符比a
。这个问题没有让我们担心确保角色的情况是相同的,只是拼写。 -
我们的下一步是将我们的字符串和
.split()
它,.reverse()
它,最后是.join()
一起取回来。 -
最后一步是检查字符串是否向前和向后相同并返回我们的结果!
相关链接
中级代码解决方案:
function palindrome(str) {
str = str.toLowerCase().replace(/[\W_]/g, '');
for(var i = 0, len = str.length - 1; i < len/2; i++) {
if(str[i] !== str[len-i]) {
return false;
}
}
return true;
}
代码说明:
-
我们首先使用相同的方法,使用
RegEx
的正则表达式替换字符串中我们不想要的字符,然后将字符串设为小写。 -
接下来,我们设置
for
循环并声明索引i
以跟踪循环。我们将转义序列设置为当i
大于字符串的长度除以2时,它告诉循环在字符串的中间点之后停止。最后我们设置i
在每个循环后递增。 -
在每个循环内部,我们要检查元素
[i]
中的字母是否等于字符串长度中的字母减去i,[str.length - i]
。每个循环,在字符串两侧检查的元素移动到更靠近中心,直到我们检查了所有字母。如果在任何时候字母不匹配,我们返回false
。如果循环成功完成,则意味着我们有一个回文,因此我们返回true
!
相关链接
- 正则表达式
高级代码解决方案(性能最佳):
//this solution performs at minimum 7x better, at maximum infinitely better.
//read the explanation for the reason why. I just failed this in an interview.
function palindrome(str) {
//assign a front and a back pointer
let front = 0
let back = str.length - 1
//back and front pointers won't always meet in the middle, so use (back > front)
while (back > front) {
//increments front pointer if current character doesn't meet criteria
if ( str[front].match(/[\W_]/) ) {
front++
continue
}
//decrements back pointer if current character doesn't meet criteria
if ( str[back].match(/[\W_]/) ) {
back--
continue
}
//finally does the comparison on the current character
if ( str[front].toLowerCase() !== str[back].toLowerCase() ) return false
front++
back--
}
//if the whole string has been compared without returning false, it's a palindrome!
return true
}
代码说明:
-
我在接受采访时得到了这个问题(剧透:我没有被录用我很快就找到了基本的解决方案,面试官告诉我要做得更好。如果他将圣经作为字符串传递,算法将花费太长时间。他希望它是即时的。
-
较简单的解决方案在长字符串上表现非常差,因为它们在比较整个字符串两次之前多次对整个字符串进行操作(toLowerCase(),replace(),split(),reverse(),join())。
-
这个解决方案的美妙之处在于它永远不需要读完整个字符串,甚至一次,知道它不是回文。如果只是通过查看两个字母就可以看出它不是一个回文,为什么要读完整个字符串呢?
-
使用while循环而不是for循环作为最佳实践 - 因为我们使用两个变量,一个是从字符串的开头开始的索引,另一个是从字符串的结尾开始。
相关链接
捐款说明:
- 请勿添加与任何现有解决方案类似的解决方案。如果您认为它**相似但更好** ,那么尝试合并(或替换)现有的类似解决方案。
- 添加解决方案的说明。
- 将解决方案分为以下类别之一 - 基本 , 中级和高级 。
- 如果您添加了任何**相关的主要内容,**请仅添加您的用户名。 ( 不要 删除任何现有的用户名 )