【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;
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要验链表是否为回文链表,可以采用以下方法: 1. 使用快慢指针找到链表的中点。 2. 将链表的后半部分反转。 3. 将链表的前半部分与反转后的后半部分进行逐一比较,如果存在不相等的节点,则该链表不是回文链表。 4. 如果链表的所有节点都比较完毕,且没有找到不相等的节点,则该链表回文链表。 具体操作步骤如下: 1. 初始化快慢指针,快指针每次移动两个节点,慢指针每次移动一个节点,直到快指针到达链表末尾。此时慢指针指向链表的中点。 2. 将链表的后半部分反转。可以使用一个新的指针从慢指针位置开始反转,每次将当前节点的next指针指向前一个节点,然后将指针向后移动一个节点,直到到达链表末尾。最后将反转后的链表的头节点保存下来。 3. 分别使用两个指针,一个指向链表的头节点,另一个指向反转后的链表的头节点。逐一比较两个指针指向的节点的值是否相等,如果存在不相等的节点,则该链表不是回文链表。 4. 如果链表的所有节点都比较完毕,且没有找到不相等的节点,则该链表回文链表。 通过以上方法,我们可以检验链表是否为回文链表。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++数据结构与算法之判断一个链表是否为回文结构的方法](https://download.csdn.net/download/weixin_38737980/14866827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [判断链表是否为回文链表leetcode-LeetCodeAlgorithm:算法问题](https://download.csdn.net/download/weixin_38660295/19945543)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [判断链表是否为回文链表leetcode-LeetCode:力码](https://download.csdn.net/download/weixin_38600696/19945643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值