<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每日一道 LeetCode (54):電話號(hào)碼的字母組合

          共 1756字,需瀏覽 4分鐘

           ·

          2020-10-17 07:21

          ?

          每天 3 分鐘,走上算法的逆襲之路。

          ?

          前文合集

          每日一道 LeetCode 前文合集

          代碼倉(cāng)庫(kù)

          GitHub:https://github.com/meteor1993/LeetCode

          Gitee:https://gitee.com/inwsy/LeetCode

          題目:電話號(hào)碼的字母組合

          難度:「中等」

          題目來(lái)源:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/

          給定一個(gè)僅包含數(shù)字 2-9 的字符串,返回所有它能表示的字母組合。

          給出數(shù)字到字母的映射如下(與電話按鍵相同)。注意 1 不對(duì)應(yīng)任何字母。

          示例:

          輸入:"23"
          輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

          說(shuō)明: 盡管上面的答案是按字典序排列的,但是你可以任意選擇答案輸出的順序。

          解題思路

          這道題看著有木有感覺(jué)很簡(jiǎn)單的樣子,至少我一開(kāi)始是覺(jué)得蠻簡(jiǎn)單的。

          先使用哈希表定義一個(gè)字典:

          static?final?Map?map?=?Map.of(
          ????'2',?"abc",?'3',?"def",?'4',?"ghi",?'5',?"jkl",
          ????'6',?"mno",?'7',?"pqrs",?'8',?"tuv",?'9',?"wxyz"
          );

          上面這個(gè)是在 JDK9 以后開(kāi)始支持的初始化方式,正好 LeetCode 也支持 JDK9 的語(yǔ)法,如果一定要用 JDK8 的話,emmmmmmmm:

          Map?map?=?new?HashMap()?{{
          ????put('2',?"abc");
          ????put('3',?"def");
          ????put('4',?"ghi");
          ????put('5',?"jkl");
          ????put('6',?"mno");
          ????put('7',?"pqrs");
          ????put('8',?"tuv");
          ????put('9',?"wxyz");
          }};

          別問(wèn)我為啥要用 JDK9 的寫法,問(wèn)就是省紙。

          接下來(lái)思考那個(gè)示例 「23」 ,首先程序先解析 2 , 2 對(duì)應(yīng)了三個(gè)字母 abc , 3 也對(duì)應(yīng)了三個(gè)字母 def ,這道題在最終輸出的結(jié)果集沒(méi)玩什么滑頭,直接就是所有的情況都排列出來(lái)就可以了,那么我可以套兩個(gè)循環(huán),直接把所有的情況全都迭代出來(lái)。

          但是題目上并沒(méi)有說(shuō)輸入的字符串一定是兩位的,如果是三位的那不就傻了。實(shí)際上是輸出的字符串有幾位就需要套幾層循環(huán),好像不是很好寫啊。。。

          這個(gè)時(shí)候,就需要用到一種不是很好理解,并且不是很好寫的方案了——遞歸。

          使用遞歸的時(shí)候并不需要指定遞歸的次數(shù),遞歸是直接遞歸到底的。

          于是就有了下面這段代碼:

          //?最終結(jié)果
          private?List?res?=?new?ArrayList<>?();
          //?組合形式
          private?StringBuilder?sb?=?new?StringBuilder();

          public?List?letterCombinations(String?digits)?{
          ????if?(digits.length()?==?0)?return?res;
          ????backtrack(digits,?0);
          ????return?res;
          }

          //?回溯函數(shù)
          public?void?backtrack(String?digits,?int?index)?{
          ????if?(index?==?digits.length())?{
          ????????res.add(sb.toString());
          ????}?else?{
          ????????char?digit?=?digits.charAt(index);
          ????????String?letters?=?map.get(digit);
          ????????int?lettersCount?=?letters.length();
          ????????for?(int?i?=?0;?i?????????????sb.append(letters.charAt(i));
          ????????????backtrack(digits,?index?+?1);
          ????????????sb.deleteCharAt(sb.length()?-?1);
          ????????}
          ????}
          }

          整段代碼并不長(zhǎng),而且看起來(lái)還很好理解,整體最核心的就是在那個(gè) for 循環(huán)里面的三句話:

          sb.append(letters.charAt(i));
          backtrack(digits,?index?+?1);
          sb.deleteCharAt(sb.length()?-?1);

          第一句話是先把當(dāng)前的值放入到我們的全局對(duì)象 sb 中,按照案例的 「23」 來(lái)演示的話就是先把 a 放到 sb 中,然后開(kāi)始遞歸進(jìn)下一次,這時(shí)候,我們第一個(gè)字符串全都是 a ,第二個(gè)字符串 3 對(duì)應(yīng)的可選值有 def ,接著我們把 d 也放到 sb 中,這時(shí) sb 中的值是 ad ,然后進(jìn)入下一次迭代,走到上面的那個(gè)判斷,把 sb 中的 ad 放入最終的輸出結(jié)果 res 中,然后遞歸往上走一層,刪除 sb 中的最后一個(gè)數(shù),這時(shí) sb 中剩下的是 a , for 循環(huán)進(jìn)入下一次循環(huán) ,像 sb 中添加一個(gè) e ,然后重復(fù)上面的過(guò)程。

          上面這段解釋有點(diǎn)繞,可以多讀幾次,或者在代碼上多打幾個(gè)斷點(diǎn)手動(dòng) debug 一下,分分鐘就懂了。




          感謝閱讀



          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻懂色av粉嫩av浪潮av | 97超碰在线免费观看 | 久草中文91 | 国产精品一区亚洲一区天堂 | www.俺去也 |