算法基礎(chǔ)——遞歸 / 回溯(三)

一劣纲、電話號碼的字母組合

  • 不同電話號碼映射不同的字母組

    • 需要保存
  • 遞歸函數(shù)處理:

    • 每一層對應(yīng)一個電話號碼:循環(huán)操作其對應(yīng)的字母組
    • 一層遞歸循環(huán)傳入電話號碼對應(yīng)的字母組
    • 調(diào)用遞歸函數(shù)特恬,傳入的字母下標(biāo)需增加舷暮,字母組合加上當(dāng)前循環(huán)的字母組中的字母
    • 結(jié)束:當(dāng)前字母組循環(huán)結(jié)束、或者 組合長度等于digital的長度+
  • String字符串拼接和StringBuilder.append()的效率問題_穆呈祥的博客-CSDN博客

    拼接字符串的效率問題(String嚼锄,StringBuffer爷辱,StringBuilder對比) - 時光.漫步 - 博客園 (cnblogs.com)

  • 執(zhí)行時間 5ms的String + 代碼:

    class Solution {
        public List<String> letterCombinations(String digits) {
            List<String> ans =  new ArrayList<>();
            if(digits.length() > 0) {
                checkBack(ans, digits, 0, "", getMap());
            }
            return ans;
        }
    
        private void checkBack(List<String> ans, String digits, int index, String combination, HashMap<Character, char[]> map) {
            if(combination.length() == digits.length()) {
                ans.add(combination);
            } else {
                char t = digits.charAt(index);
                char[] charArr = map.get(t);
                for(int i = 0; i < charArr.length; i++) {
                    checkBack(ans, digits, index + 1, combination + charArr[i], map);
                }
            }
        }
    
        private HashMap<Character, char[]> getMap() {
            HashMap<Character, char[]> map = new HashMap<>();
            map.put('2', new char[] {'a', 'b', 'c'});
            map.put('3', new char[] {'d', 'e', 'f'});
            map.put('4', new char[] {'g', 'h', 'i'});
            map.put('5', new char[] {'j', 'k', 'l'});
            map.put('6', new char[] {'m', 'n', 'o'});
            map.put('7', new char[] {'p', 'q', 'r', 's'});
            map.put('8', new char[] {'t', 'u', 'v'});
            map.put('9', new char[] {'w', 'x', 'y', 'z'});
            return map;
        }
    }
    
  • 執(zhí)行用時 0ms的StringBulider代碼:

    class Solution {
        public List<String> letterCombinations(String digits) {
            List<String> ans =  new ArrayList<>();
            if(digits != null && digits.length() > 0) {
                checkBack(ans, digits, 0, new StringBuilder(), getMap());
            }
            return ans;
        }
    
        private void checkBack(List<String> ans, String digits, int index, StringBuilder combination, HashMap<Character, char[]> map) {
            if(combination.length() == digits.length()) {
                ans.add(combination.toString());
            } else {
                char t = digits.charAt(index);
                char[] charArr = map.get(t);
                for(int i = 0; i < charArr.length; i++) {
                    checkBack(ans, digits, index + 1, combination.append(charArr[i]), map);
                    combination.deleteCharAt(combination.length() - 1);
                }
            }
        }
    
        private HashMap<Character, char[]> getMap() {
            HashMap<Character, char[]> map = new HashMap<>();
            map.put('2', new char[] {'a', 'b', 'c'});
            map.put('3', new char[] {'d', 'e', 'f'});
            map.put('4', new char[] {'g', 'h', 'i'});
            map.put('5', new char[] {'j', 'k', 'l'});
            map.put('6', new char[] {'m', 'n', 'o'});
            map.put('7', new char[] {'p', 'q', 'r', 's'});
            map.put('8', new char[] {'t', 'u', 'v'});
            map.put('9', new char[] {'w', 'x', 'y', 'z'});
            return map;
        }
    }
    
  • 不僅時間上耗時不同晕翠,內(nèi)存同樣是不同,StringBuilder比String+ 少消耗內(nèi)存

二担映、括號生成

  • 組合問題

  • n代表有 n對括號

    • 首先獲得所有括號組合
    • 考慮去除無效括號:
      • 去除條件:左括號可用數(shù)量大于0废士、右括號未使用數(shù)量大于左括號
  • class Solution {
        public List<String> generateParenthesis(int n) {
            List<String> ans = new ArrayList<>();
            checkBack(ans, n * 2, n, n, new StringBuilder());
            return ans;
        }
    
        private void checkBack(List<String> ans, int n, int left, int right, StringBuilder combination) {
            if(n <= 0) {
                ans.add(combination.toString());
            } else {
                //左括號可用數(shù)量大于0
                if(left > 0) {
                    checkBack(ans, n - 1, left - 1, right, combination.append('('));
                    combination.deleteCharAt(combination.length() - 1);
                }
                //右括號未使用數(shù)量大于左括號
                if(right > left) {
                    checkBack(ans, n - 1, left, right - 1, combination.append(')'));
                    combination.deleteCharAt(combination.length() - 1);
                }
            }
        }
    }
    

三、單詞搜索

  • 深度優(yōu)先搜索:第一個字符在數(shù)組中蝇完,就開始深度搜索

  • 四個方向都要檢查

  • 利用記憶數(shù)組確定該元素是否還可作為單詞部分

  • class Solution {
        public boolean exist(char[][] board, String word) {
            for(int i = 0; i < board.length; i++) {
                for(int j = 0; j < board[0].length; j++) {
                    if(word.charAt(0) == board[i][j] && checkBack(board, word, 0, new int[board.length][board[0].length], i, j)) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        private boolean checkBack(char[][] board, String word, int index, int[][] memory, int i, int j) {
            if(index == word.length()) {
                return true;
            }
            if(i >= 0 && i < board.length && j >= 0 && j < board[0].length && memory[i][j] == 0 && index < word.length() && board[i][j] == word.charAt(index)) {
                memory[i][j] = 1;
                boolean ans =  checkBack(board, word, index + 1, memory, i - 1, j) ||
                        checkBack(board, word, index + 1, memory, i + 1, j) ||
                        checkBack(board, word, index + 1, memory, i, j - 1) ||
                        checkBack(board, word, index + 1, memory, i, j + 1);
                memory[i][j] = 0;
                return ans;
            }
            return false;
        }
    }
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末官硝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子短蜕,更是在濱河造成了極大的恐慌氢架,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朋魔,死亡現(xiàn)場離奇詭異岖研,居然都是意外死亡,警方通過查閱死者的電腦和手機警检,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門孙援,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扇雕,你說我怎么就攤上這事拓售。” “怎么了洼裤?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵邻辉,是天一觀的道長溪王。 經(jīng)常有香客問我,道長值骇,這世上最難降的妖魔是什么莹菱? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮吱瘩,結(jié)果婚禮上道伟,老公的妹妹穿的比我還像新娘。我一直安慰自己使碾,他們只是感情好蜜徽,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著票摇,像睡著了一般拘鞋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上矢门,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天盆色,我揣著相機與錄音,去河邊找鬼祟剔。 笑死隔躲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的物延。 我是一名探鬼主播宣旱,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼叛薯!你這毒婦竟也來了浑吟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤案训,失蹤者是張志新(化名)和其女友劉穎买置,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體强霎,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡忿项,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了城舞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轩触。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖家夺,靈堂內(nèi)的尸體忽然破棺而出脱柱,到底是詐尸還是另有隱情,我是刑警寧澤拉馋,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布榨为,位于F島的核電站惨好,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏随闺。R本人自食惡果不足惜日川,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矩乐。 院中可真熱鬧龄句,春花似錦、人聲如沸散罕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽欧漱。三九已至职抡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間硫椰,已是汗流浹背繁调。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留靶草,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓岳遥,卻偏偏與公主長得像奕翔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浩蓉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容