Skip to content

Commit

Permalink
refactor(string): provide detailed problem-solving approach to 125
Browse files Browse the repository at this point in the history
  • Loading branch information
RayJune committed Jul 19, 2024
1 parent 916826a commit a6b3db7
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 17 deletions.
22 changes: 17 additions & 5 deletions src/string/125-valid-palindrome/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,30 @@
*/

/**
* Time Complexity: O(n) = toLowerCase/replace/split/reverse/join 操作
* Space complexity: O(n) = split 产生的数组长度 O(n) + filteredS/reversedS 长度
* Auxiliary complexity: O(n) = split 产生的数组长度 O(n) + filteredS/reversedS 长度
* 其中 n 为字符串 s 的长度
* 输入一个字符串,判断它是否是回文字符串。
* 注意:
* 1. 只考虑字母和数字
* 2. 忽略字母的大小写
* 3. 指定空字符串为回文字符串
*
* 思路:
* 1. 大小写统一,用 .toLowerCase 处理
* 2. 正则匹配,筛选出由字母和数字所组成的字符串
* 3. 字符串反转,.split + .reverse + .join 方法
* 4. 将反转字符串与原字符串作比较得出结果
*
* Time Complexity: O(n) = 遍历次数
* Space Complexity: O(n) = 创建的数组长度 / 创建的字符串长度
* Auxiliary Complexity: O(n) = 创建的数组长度
* 其中 n 是字符串 s 的长度
*
* @param {string} s
* @returns {boolean}
*/
function isPalindrome(s) {
const filteredS = s
.toLowerCase()
.replace(/[^a-z0-9]/g, '');
.replaceAll(/[^a-z0-9]/g, '');
const reversedS = filteredS
.split('')
.reverse()
Expand Down
40 changes: 35 additions & 5 deletions src/string/125-valid-palindrome/optimize.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,33 @@
*/

/**
* Time Complexity: O(n) = toLowerCase/replace 操作 O(n) + for 循环 O(n / 2)
* Space complexity: O(n) = filteredS 长度
* Auxiliary complexity: O(n) = filteredS 长度
* 输入一个字符串,判断它是否是回文字符串
* 注意:
* 1. 只考虑字幕和数字
* 2. 忽略字母的大小写
* 3. 指定空字符串为回文字符串
*
* 思路:
* 1. 统一大小写,.toLowerCase
* 2. 正则匹配筛选出字母和数字组成的字符串
* 3. 遍历筛选后的字符串,利用 s[i] === s[len - i - 1] 来判断是否是回文字符串
*
* Time Complexity: O(n) = 遍历次数
* Space Complexity: O(n) = 创建的字符串长度
* Auxiliary Complexity: O(n) = 创建的字符串长度
* 其中 n 是字符串 s 的长度
*
* @param {string} s
* @returns {boolean}
*/
function isPalindrome(s) {
const filteredS = s.toLowerCase().replace(/[^a-z0-9]/g, '');
const filteredS = s
.toLowerCase()
.replaceAll(/[^a-z0-9]/g, '');
const len = filteredS.length;
const pivot = Math.floor(len / 2);

for (let i = 0; i < Math.floor(len / 2); i++) {
for (let i = 0; i < pivot; i++) {
if (filteredS[i] !== filteredS[len - i - 1]) {
return false;
}
Expand All @@ -45,4 +60,19 @@ function isPalindrome(s) {
return true;
}

/**
* 其中 for 循环的部分也可以用 .every 方法,可读性更好
*/
// function isPalindrome(s) {
// const filteredS = s
// .toLowerCase()
// .replaceAll(/[^a-z0-9]/g, '');
// const len = filteredS.length;

// return filteredS
// .split('')
// .every((char, i) => char === filteredS[len - i - 1]);
// }


module.exports = isPalindrome;
25 changes: 18 additions & 7 deletions src/string/125-valid-palindrome/optimize2.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,36 @@
*/

/**
* Two Pointers
* 输入一个字符串,判断它是否是回文字符串
* 注意:
* 1. 只考虑字母和数字
* 2. 忽略字母的大小写
* 3. 指定空字符串为回文字符串
*
* Time Complexity: O(n) = 内外层 while 循环次数之和 O(n)
* Space complexity: O(1)
* Auxiliary complexity: O(1)
* 思路:
* Two Pointers 双指针,原地做比较,不创建新的字符串、数组
* 1. 创建 left right 两个下标,分别代表要比较的前后对称两个值的下标
* 2. 遍历字符串 s,以此判断两个下标对应的值是否是字母或数字,如果不是则把对应下标向前/向后移动,直到为字母或数字值为止
* 3. 依次判断 left right 对应的值
*
* Time Complexity: O(n) = 遍历次数
* Space Complexity: O(1)
* Auxiliary Complexity: O(1)
* 其中 n 是字符串 s 的长度
*
* @param {string} s
* @returns {boolean}
*/
function isPalindrome(s) {
const skip = char => /[^a-zA-Z0-9]/.test(char);
let left = 0;
let right = s.length - 1;
const isSkip = char => /[^a-z0-9]/i.test(char);

while (left < right) {
while (left < right && skip(s[left])) {
while (left < right && isSkip(s[left])) {
left += 1;
}
while (left < right && skip(s[right])) {
while (left < right && isSkip(s[right])) {
right -= 1;
}
if (s[left].toLowerCase() !== s[right].toLowerCase()) {
Expand Down

0 comments on commit a6b3db7

Please sign in to comment.