LeetCode JavaScript实现 回文链表(回文字符串) 题型汇总(双指针解法)
Posted YuLong~W
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode JavaScript实现 回文链表(回文字符串) 题型汇总(双指针解法)相关的知识,希望对你有一定的参考价值。
234. 回文链表 / 面试题 02.06. 回文链表
原题链接:234. 回文链表 / 面试题 02.06. 回文链表
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
}
解题思路:
① 数组+双指针: 方法容易理解 但是执行时间及空间效率不及方法②
- 定义一个新数组,用push方法将链表的值依次存入
- 利用头尾双指针,通过条件判断,一个向前移,一个向后移
var isPalindrome = function(head) {
let vals=[];
while(head!=null){
//将所有的值存入数组当中
vals.push(head.val);
head=head.next;
}
// 定义双指针 一个不断后移,一个不断前移
let i=0;
let j=vals.length-1;
while(i<j){
if(vals[i]!=vals[j]){
return false;
}
i++;
j--;
}
return true;
}
② 反转链表+双指针:执行时间和内存效率更高
- 定义查找中间结点函数,通过快慢双指针完成。如果是奇数结点 则为最中间 如果是偶数结点 则为前半部分最后一个结点
- 定义反转链表函数,具体思路详解:【LeetCode】 JavaScript实现 反转链表(三种思路)
- 依次调用后,进行判断,利用双指针,一个从头开始,一个从中间开始,不断后移
var isPalindrome = function(head) {
let half=halflist(head); //找到找到前半部分的尾结点
let halfhead=reverlist(half.next); //反转后半部分链表 应该是half.next 不能是half
//判断是否回文
//定义双指针 一个从头开始 一个从中间开始
let p1=head;
let p2=halfhead;
let flag=true;
while(flag && p2!=null){
if(p1.val!=p2.val){
flag=false;
}
p1=p1.next;
p2=p2.next;
}
return flag;
};
//查找中间结点 定义快慢指针 查找中间结点
//如果是奇数结点 则为最中间 如果是偶数结点 则为前半部分最后一个结点
const halflist=(head)=>{
let fast=head;
let slow=head;
while(fast.next!=null&&fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
return slow;
}
//反转链表
const reverlist = (head)=>{
let prev=null;
let curr=head;
let temp=null;
while(curr!==null){
temp=curr.next;
curr.next=prev;
prev=curr;
curr=temp;
}
return prev;
}
125. 验证回文串
原题链接:125. 验证回文串
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function(s) {
};
解题思路:
①:正则表达式+双指针:
查找正则表达式规则: JavaScript 正则表达式、String类方法
- 先利用正则表达式进行过滤
- 再用利用左右双指针前后判断
var isPalindrome = function(s) {
//使用正则表达式进行过滤
let reg=/[a-zA-Z0-9]/;
let str='';
for(let i=0;i<s.length;i++){
if(reg.test(s[i])){
str+=s[i];
}
}
//将大小写统一
str=str.toLowerCase();
//利用双指针前后进行判断
let left=0;
let right=str.length-1;
while(left<right){
if(str[left]!=str[right]){
return false;
}
left++;
right--;
}
return true;
};
② 正则+内置对象相关方法: 暴力解法
查找相关方法:JavaScript 对象、内置对象(Math、Date、数组、String)及值类型和引用类型
- 利用 replace() 方法替代掉不符合规定的参数
- 再利用 split() 方法进行切割, 并用反转 reverse() 方法
- 再用 join() 方法连接
var isPalindrome = function(s) {
let str1 = s.toLowerCase().replace(/[^a-zA-Z0-9]/g,''); //利用replace方法 拿''替代掉不符合规定的参数
let str2 = str1.split('').reverse().join(''); //再利用split方法 拿''进行切割, 并用反转reverse方法 再用join方法拿''连接
return str1===str2;
};
680. 验证回文字符串 Ⅱ
原题链接: 680. 验证回文字符串 Ⅱ
/**
* @param {string} s
* @return {boolean}
*/
var validPalindrome = function(s) {
}
解题思路:
- 先利用双指针判断是否为回文字符串
- 如果不是,调用二次判断是否回文串的函数
- 该函数定义的参数子串,可以是(left+1,right) 或者(left,right-1)即可以删除一个字符 再进行判断
- 当这两个子串中至少有一个是回文串时,就说明原始字符串删除一个字符之后就以成为回文串
var validPalindrome = function(s) {
//利用双指针前后进行判断
let left=0;
let right=s.length-1;
while(left<right){
if(s[left]!=s[right]){ //如果不相等 可以进行二次判断 调用again函数 参数传递可以变为left+1 或者 right-1
return again(s,left+1,right)||again(s,left,right-1);
}
left++;
right--;
}
return true;
};
//二次判断函数
function again(str,m,n){
while(m<n){
if(str[m]!=str[n]){
return false;
}
m++;
n--;
}
return true;
}
1332. 删除回文子序列
原题链接: 删除回文子序列
/**
* @param {string} s
* @return {number}
*/
var removePalindromeSub = function(s) {
};
解题思路: 类似于脑筋急转弯 和双指针没有关系
- 注意读题:可以删除回文子序列,而不是回文字符串。所以没有顺序,子序列可以是不连续的
- 因此,只有三种情况:空字符串(0)回文字符串(1)非回文字符串(2 即先删除a 再删除b)
var removePalindromeSub = function(s) {
//删除子序列 而不是子字符串 子序列可以是不连续的 只有三种情况
//空字符串(0)回文字符串(1)非回文字符串(2 即先删除a 再删除b)
if (s.length === 0) return 0;
for (let left = 0, right = s.length - 1; left < right; ++left, --right) {
if (s[left] !== s[right]) return 2;
}
return 1;
};
以上是关于LeetCode JavaScript实现 回文链表(回文字符串) 题型汇总(双指针解法)的主要内容,如果未能解决你的问题,请参考以下文章