2018年搜狗秋招前端笔试题:字符串删除

昨天做了搜狗前端笔试题,其中有一道题目是为字符串添加一个删除方法,给定一个参数n,求从该字符串删除n个字符组成的不同子串个数。题目看起来很简单,但是并不好编写。如果字符串字符各不相同还好说,直接可以使用排列组合公式来得到最终的个数;否则的话就得考虑删除后可能会产生相同的子串了。这样的话就得做一个Set来保存所有的字符串了。(我是这样想的,不知道还没有什么其他的方法。)当时想的是递归,但迫于时间没有写出来,所以趁着最近时间充裕,把算法实现了出来。如有错误,请不吝指正。

console.log('---从长为m字符串删除k个字符组成的不同子串个数---');
String.prototype.delete=function(k){
  if(k==0)return 1;
  var l=this.length;
  var tmp=[];
  var set=new Set();
  help(this.split(''),0,k,tmp);
  //print(set)
  return set.size;
  function help(arr,start,k,tmp){
    if(k==0){
      var rest=arr.filter((item,index)=>tmp.indexOf(index)==-1);
      set.add(rest.join(''));
      return;
    }
    if(l-start-11)return;
    for(var i=start;i1,k-1,tmp);
      tmp.pop(i);
    }
  }
}
console.log('------test------');
console.log('segeg'.delete(0))  //1
console.log('segeg'.delete(1))  //5
console.log('segeg'.delete(2))  //8
console.log('segeg'.delete(3))  //6
console.log('segeg'.delete(4))  //3
console.log('segeg'.delete(5))  //1

算法的关键是递归函数help(arr,start,k,tmp)。它接收四个参数,arr是字符数组,把原来的字符串转为了数组。start是开始位置,表示从start开始的位置都可以删除,之前的保持不变。k表示还能删除几个字符,当k=0时递归停止。tmp是保存的删除的字符索引。set保存删除字符之后的数组,该数组是过滤tmp中保存的索引得到的。最后只返回set的长度就可以了。每次递归的时候选择一个字符,把它保存下来,start+1,k-1,继续递归,等它完成后弹出该字符,继续下一个字符的递归。

最近感觉自己的递归水平太差了,笔试题的递归基本都写不出来,像全排列什么的,所以要加强联系了。这道题是我自己理解的解法,如果您有更好的方法,欢迎讨论。

你可能感兴趣的:(web)