字符串看到 ”回文“ 尝试双指针

1,039 阅读2分钟

最近在看数据结构和算法,努力总结出道~

TL:DR

上一篇文说过有序的数组,试试用指针法遍历

指针的本质是,记住遍历的进度,从而减少无效遍历的范围。

同理,对于字符串来说,如果是回文,有着天然的对称性,非常适合用指针法缩小遍历范围。

什么是回文

回文:正着读和倒着读都一模一样的字符串。

特点:对称!对称!对称!

判断是不是回文的快速 api 方法:str=>str.split('').reverse().join() === str

非 Api 的朴素方法:左右两个指针,只要相等就往中间移动,遍历完则是回文,否则就不是回文

function isPalindrome(str) {
  let len = str.length;
  let L = 0;
  let R = len - 1;
  // 指针法基本都是while,遍历的条件是左指针始终在左边
  while (L < R) {
    if (str[L] !== str[R]) {
      return false;
    }
    L++;
    R--;
  }
  return true;
}

练习:回文类的字符串题目

string1

当然如果不知道对称性的情况,可能会暴力的从第一个字符串开始试着删除,然后判断剩下的是不是回文,方法肯定可行,但没有利用好对称性。

其实这里,和判断是不是回文类似,左右双指针,当不相等的时候,尝试对左指针字符和右指针字符尝试进行“跳过”,看看区间在 [L+1, R] 或 [L, R-1] 的字符串是否回文。

function validPalindrome(str) {
  const len = str.length;
  let L = 0;
  let R = len - 1;
  // 循环条件加个相等,这样循环后面就是不相等的位置
  while (L < R && str[L] === str[R]) {
    L++;
    R--;
  }
  // 判断特定区间是不是回文
  if (isPalindrome(L + 1, R) || isPalindrome(L, R - 1)) {
    return true;
  }
  return false;

  // 方法稍微改成特定区间
  function isPalindrome(L, R) {
    while (L < R) {
      if (str[L] !== str[R]) {
        return false;
      }
      L++;
      R--;
    }
    return true;
  }
}

可以看下官方视频

引用