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实现 回文链表(回文字符串) 题型汇总(双指针解法)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 234 回文链表

算法热门:回文链表(LeetCode 234)

LeetCode234. 回文链表

Leetcode-234. 回文链表

LeetCode——回文链表

LeetCode——回文链表