学习记录:js算法(十三):移动零、验证回文串

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意: 必须在不复制数组的情况下原地对数组进行操作。

示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:
输入: nums = [0]
输出: [0]

我的思路
万变不离其宗: 循环
网上思路
双指针

我的思路

var moveZeroes = function (nums) {
    let len = nums.length - 1
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len - i; j++) {
            if (nums[j] === 0) {
                nums[j] = nums[j + 1]
                nums[j + 1] = 0
            }
        }
    }
};

讲解
改变冒泡排序,这种不需要讲解了吧,唯一需要说明的是:let len = nums.length - 1,为什么要 减去1 呢?是因为在第二个循环中,j+1 会找到数组的最后一位,如果长度是 nums.length 的话,会找不到 j+1

网上思路

var moveZeroes = function (nums) {
    let lastNonZeroIndex = 0; // 指向下一个非零元素的位置
    // 遍历数组
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] !== 0) {
            // 如果当前元素不是 0,将其放到 lastNonZeroIndex 位置
            nums[lastNonZeroIndex] = nums[i];
            lastNonZeroIndex++; // 移动指针
        }
    }
    // 将剩余的元素设置为 0
    for (let i = lastNonZeroIndex; i < nums.length; i++) {
        nums[i] = 0;
    }
};

讲解
其实很好理解

  1. 初始化一个指针 **lastNonZeroIndex:指向数组第一个元素 **
  2. 如果当前元素不是 0,将其放到 lastNonZeroIndex 指向的位置,然后 lastNonZeroIndex++,目的是: 移动指针,为下一个非零元素准备位置
  3. 这时 lastNonZeroIndex:指向下一个非零的元素

验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。

示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

示例 2:
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。

示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。

我的思路
简单,使用正则完成条件后,只需要将字符串转成数组后在翻转,然后将翻转的数组转成字符串之后,再比较。
网上思路
双指针

我的思路

var isPalindrome = function (s) {
    let str = s.toLowerCase().replace(/[^a-z0-9]/g, '')
    return str === str.split("").reverse().join("") ? true : false
};

讲解

  1. s.toLowerCase(): 将字符串转换为小写,这样在比较时就不需要考虑大小写的差异。
  2. 正则表达式中:
    • /[^a-z0-9]/g :这个正则表达式的含义是匹配所有非字母(a-z)和非数字(0-9)的字符。
    • g :这个标志表示全局匹配,即替换字符串中所有符合条件的字符。
    • ‘’ :将匹配到的字符替换为空字符串,从而移除它们。
  3. 然后字符串转数组,数组翻转后再转字符串,最后对比即可。

网上思路

var isPalindrome = function (s) {
    // 使用正则表达式清洗字符串
    const str = s.toLowerCase().replace(/[^a-z0-9]/g, '');
    let left = 0;
    let right = str.length - 1;
    // 使用双指针比较
    while (left < right) {
        if (str[left] !== str[right]) {
            return false; // 不是回文
        }
        left++;
        right--;
    }
    return true; // 是回文
};

讲解

  1. 使用正则将字符串转换为小写并移除所有非字母数字字符。
  2. left 从前往后,right 从后往前。
  3. while 循环 中,比较 str[left]str[right]
  4. 如果字符相等,继续移动 leftright 指针。

总结

双指针:使用两个指针,分别从数据结构的两端或某个特定位置开始移动。根据某种条件,移动一个或两个指针,直到满足特定条件或遍历完整个数据结构。没了,这两题感觉用不用双指针都一样,不像之前学习中, Map()对象使用栈 给我的印象还是深刻的,可能也是刚做双指针的题目吧,看看后续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值