每周算法3

本文介绍了多种字符串处理算法,包括使用KMP算法检查重复子字符串、生成外观数列、验证赎金信中字符是否可用、计算二进制子串数量、查找数组中的字符串匹配项、反转字符串、验证回文串、判断回文排列可能性、求最长回文子串,以及删除回文子序列。这些算法展示了字符串操作在信息技术领域的广泛应用。
摘要由CSDN通过智能技术生成

1.重复的子字符串

  • 这道题主要用到KMP算法,getNext()函数找到前缀表。
/**
 * @param {string} s
 * @return {boolean}
 */
var repeatedSubstringPattern = function(s) {
  let len = s.length
  if(len<=1){
    return false
  }
  let getNext=(next,s)=>{
    next[0]=0
    let j=0
    for(let i=1;i<s.length;i++){
      while(j>0&&s[j]!==s[i]){
        j=next[j-1]
      }
      if(s[j]==s[i]) j++
      next[i]=j
    }
  }
  let res = []
  getNext(res,s)
  if(res[len-1]!=0&&len%(len-res[len-1])===0){ 
    return true
  }else{
    return false
  }
};

2.外观数列

/**
 * @param {number} n
 * @return {string}
 */
var countAndSay = function(n) {
  let res=[]
  res[0]="1"
  res[1]="11"
  let num=1
  for(let i=1;i<n;i++){
    let L=0,R=L+1
    num=1
    while(R<res[i].length){
     if(res[i][L]==res[i][R]){
        num++
        R++
      }
      if(res[i][L]!=res[i][R]){
        if(L==0){
          res[i+1]=""
        }
        res[i+1]+=num
        res[i+1]+=res[i][L]
        num=1
        if(R==res[i].length-1){
          res[i+1]+=num
          res[i+1]+=res[i][R]
        }
        L=R
        R=L+1
      }
    }
  }
  return res[n-1]
};

3.赎金信

/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) {
  let index
  let arr = magazine.split("")
  for(let i=0;i<ransomNote.length;i++){
    index = arr.indexOf(ransomNote[i])
    if(index!=-1){
      arr.splice(index,1)
    }else{
      return false
    }
  }
  return true
};

4.计数二进制子串

/**
 * @param {string} s
 * @return {number}
 */
var countBinarySubstrings = function(s) {
    let ptr = 0, n = s.length, last = 0, ans = 0;
    while (ptr < n) {
        const c = s.charAt(ptr);
        let count = 0;
        while (ptr < n && s.charAt(ptr) === c) {
            ++ptr;
            ++count;
        }
        ans += Math.min(count, last);
        last = count;
    }
    return ans;
};

5.数组中的字符串匹配

/**
 * @param {string[]} words
 * @return {string[]}
 */
var stringMatching = function(words) {
  let len = words.length
  let res = []
  let j
  for(let i=0;i<len;i++){
    for(j=i+1;j<len;j++){
      if(words[i].length>words[j].length){
        if(words[i].indexOf(words[j])!=-1){
          res.push(words[j])
          words.splice(j,1)
          j--
          len--
        }
      }
      if(words[j].length>words[i].length){
        if(words[j].indexOf(words[i])!=-1){
          res.push(words[i])
          words.splice(i,1)
          i--
          j=i+1
          if(i==-1){
            i=0
          }
          
          len--
        }
      }
    }
  }
  return res
};

6.反转字符串Ⅱ

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function(s, k) {
  let arr = s.split("")
  let L=0,num=0,t=[],len = s.length
  if(len<=k){
    return arr.reverse().join("")
  }
  while(L<len){
    L++
    num++
    if(num==k){
      t=s.substr(L-k,k).split('').reverse()
      arr.splice(L-k,k,...t)
    }
    if(L>=len&&num<k){
      t=s.substr(L-k+1,num).split('').reverse()
      arr.splice(L-k+1,num,...t)
    }
    if(num>=2*k){
      num=0
      t=[]
    }
  }
  
  return arr.join("")
};

7.验证回文字符串Ⅱ

/**
 * @param {string} s
 * @return {boolean}
 */
var isPali = function(str,l,r){
  while(l<r){
    if(str[l]!==str[r]){
      return false
    }
    l++
    r--
  }
  return true
}

var validPalindrome = function (str) {
  let l=0,r=str.length-1;
  while(l<r){
    if(str[l]!==str[r]){
      return isPali(str,l+1,r)||isPali(str,l,r-1)
    }
    l++
    r-- 
  }
  return true
}

8.回文排列

/**
 * @param {string} s
 * @return {boolean}
 */
var canPermutePalindrome = function(s) {
    let a=s.split("")
    let len = a.length
    let L=0,R=len-1
    while(L<=R){
      if(a[L]==a[R]){
        L++
        R--
      }else{
        let str = a.slice(L+1,R)
        let index = str.indexOf(a[L])
        if(index!=-1){
          t = a[index+L+1]
          a[index+L+1]=a[R]
          a[R] = t
          L++
          R--
        }else if(len%2==0){
          return false
        }else if(len%2!=0){
          a.splice(L,1)
          len = a.length
          R--
        }
      }
    }
    return true
};

9.最长回文串

/**
 * @param {string} s
 * @return {number}
 */
var longestPalindrome = function(s) {
  let a=s.split("")
    let len = a.length
    let L=0,R=len-1,num=0
    while(L<=R){
      if(a[L]==a[R]){
        L++
        R--
      }else{
        let str = a.slice(L+1,R)
        let index = str.indexOf(a[L])
        if(index!=-1){
          t = a[index+L+1]
          a[index+L+1]=a[R]
          a[R] = t
          L++
          R--
        }else{
          a.splice(L,1)
          len = a.length
          R--
          num++
        }
      }
    }
    let res = a.length
    if(res%2==0&&num>0){
      res+=1
    }
    return res
};
  • 第二种思路(用Unicode编码存次数):
/**
 * @param {string} s
 * @return {number}
 */
var longestPalindrome = function(s) {
  let charTimeAry = new Array(58).fill(0);
  for(let char of s){
    charTimeAry[char.charCodeAt() - 65] += 1;
  }
  let maxSize = 0
  for(let time of charTimeAry){
    maxSize += parseInt((time / 2), 10) * 2; 
  }
  return maxSize < s.length ? maxSize + 1 : maxSize;
};

10.删除回文子序列

  • (这道题一定要看懂题)
/**
 * @param {string} s
 * @return {number}
 */
var removePalindromeSub = function(s) {
    return s.length === 0 ? 0 : s.split('').reverse().join('') === s ? 1 : 2;
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值