1. 程式人生 > 實用技巧 >CVE-2017-10271

CVE-2017-10271

上升下降字串

給你一個字串s,請你根據下面的演算法重新構造字串:

  • s中選出最小的字元,將它接在結果字串的後面。
  • s剩餘字元中選出最小的字元,且該字元比上一個新增的字元大,將它接在結果字串後面。
  • 重複步驟2,直到你沒法從s中選擇字元。
  • s中選出最大的字元,將它接在結果字串的後面。
  • s剩餘字元中選出最大的字元,且該字元比上一個新增的字元小,將它接在結果字串後面。
  • 重複步驟5,直到你沒法從s中選擇字元。
  • 重複步驟16,直到s中所有字元都已經被選過。
  • 在任何一步中,如果最小或者最大字元不止一個,你可以選擇其中任意一個,並將其新增到結果字串。

請你返回將s中字元重新排序後的結果字串。

示例

輸入:s = "aaaabbbbcccc"
輸出:"abccbaabccba"
解釋:第一輪的步驟 1,2,3 後,結果字串為 result = "abc"
第一輪的步驟 4,5,6 後,結果字串為 result = "abccba"
第一輪結束,現在 s = "aabbcc" ,我們再次回到步驟 1
第二輪的步驟 1,2,3 後,結果字串為 result = "abccbaabc"
第二輪的步驟 4,5,6 後,結果字串為 result = "abccbaabccba"
輸入:s = "rat"
輸出:"art"
解釋:單詞 "rat" 在上述演算法重排序以後變成 "art"
輸入:s = "leetcode"
輸出:"cdelotee"

題解

/**
 * @param {string} s
 * @return {string}
 */
var sortString = function(s) {
    let hashTable = Object.create(null);
    let base = "a".charCodeAt();
    for(let i=0;i<26;++i) hashTable[String.fromCharCode(base+i)] = 0;
    Array.prototype.forEach.call(s, v => hashTable[v]++);
    let target = "";
    while(target.length < s.length){
        for(let i=0;i<26;++i) {
            let key = String.fromCharCode(base+i);
            if(hashTable[key]){
                target += key;
                hashTable[key]--;
            }
        }
        for(let i=25;i>=0;--i) {
            let key = String.fromCharCode(base+i);
            if(hashTable[key]){
                target += key;
                hashTable[key]--;
            }
        }
    }
    return target;
};

思路

題目挺長的,其實就是普通的字串的操作,並且由於題目中說明了是純小寫字母,也就是總量是確定的,那麼就可以不使用排序去統計數量,之後的操作正好也是順序遍歷與逆序遍歷即可完成的操作,拼接字串返回即可。首先定義一個純物件作為雜湊表來記錄字串每種字元的個數,之後定義小寫字元的基準數值aASCII碼值,之後構建一個26個小寫字母的迴圈,將初始雜湊表的鍵對應的值定義為0,迴圈字串,將統計相應字母出現的次數,定義目標字串,如果目標字串與給定的字串長度相等則退出迴圈,之後定義一個26字母正向迴圈,如果在雜湊表中這個字母的值大於0則將其拼接到目標字串並將該值減1,之後定義一個26字母的逆向迴圈,按照同樣的規則將字元拼接,之後完成迴圈並返回目標字串即可。

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://leetcode-cn.com/problems/increasing-decreasing-string/