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-1<k-1)return;
    for(var i=start;i<l;i++){
      tmp.push(i);
      help(arr,i+1,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,繼續遞歸,等它完成後彈出該字符,繼續下一個字符的遞歸。

最近感覺自己的遞歸水平太差了,筆試題的遞歸基本都寫不出來,像全排列什麼的,所以要加強聯繫了。這道題是我自己理解的解法,如果您有更好的方法,歡迎討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章