1. 程式人生 > >Leetcode演算法Java全解答--17. 電話號碼的字母組合

Leetcode演算法Java全解答--17. 電話號碼的字母組合

Leetcode演算法Java全解答–17. 電話號碼的字母組合

題目

給定一個僅包含數字 2-9 的字串,返回所有它能表示的字母組合。

給出數字到字母的對映如下(與電話按鍵相同)。注意 1 不對應任何字母。 digitToLetter[‘2’]=“abc”; digitToLetter[‘3’]=“def”; digitToLetter[‘4’]=“ghi”; digitToLetter[‘5’]=“jkl”; digitToLetter[‘6’]=“mno”; digitToLetter[‘7’]=“pqrs”; digitToLetter[‘8’]=“tuv”; digitToLetter[‘9’]=“wxyz”;

示例:


示例:

輸入:"23"
輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
說明:
儘管上面的答案是按字典序排列的,但是你可以任意選擇答案輸出的順序。

想法

  1. 迴圈0~length-1

將原陣列中的值加上當前值得可能性

比如第一個數字2,對應的就是abc,這時 候陣列中的值就是[a,b,c]

輪到下一個數字3,對應的是def,就把a拼上d/e/f

返回陣列 2. 回溯法

把每個數字當作遞迴的一層,每一層中先列舉一個字母,

遞迴進入下一層,再刪除這個字母,回到上一個狀態,列舉下一個字母。

遞迴結束標誌是遞迴了digits.lengtgh層,即字母組合長度等於digits長度,

遞迴結束得到一個符合的字母組合,加入list。等於是在迴圈中套遞迴

結果

  •  超過99%的測試案例
    
  •  時間複雜度:n2
    
  •  空間複雜度:n
    

總結

沒有用遞迴的方式,直接使用迭代的方法

程式碼

我的答案

/**************************************
* 題目
給定一個僅包含數字 2-9 的字串,返回所有它能表示的字母組合。

給出數字到字母的對映如下(與電話按鍵相同)。注意 1 不對應任何字母。
digitToLetter['2']="abc";
digitToLetter['3']="def";
digitToLetter['4']="ghi";
digitToLetter['5']="jkl";
digitToLetter['6']="mno";
digitToLetter['7']="pqrs";
digitToLetter['8']="tuv";
digitToLetter['9']="wxyz";

示例:

輸入:"23"
輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
說明:
儘管上面的答案是按字典序排列的,但是你可以任意選擇答案輸出的順序。
**************************************/

/**************************************
*
* 想法:
*      1. 迴圈0~length-1
*          將原陣列中的值加上當前值得可能性
*              比如第一個數字2,對應的就是abc,這時候陣列中的值就是[a,b,c]
*              輪到下一個數字3,對應的是def,就把a拼上d/e/f
*          返回陣列
*      2. 回溯法
*          把每個數字當作遞迴的一層,每一層中先列舉一個字母,
*          遞迴進入下一層,再刪除這個字母,回到上一個狀態,列舉下一個字母。
*          遞迴結束標誌是遞迴了digits.lengtgh層,即字母組合長度等於digits長度,
*          遞迴結束得到一個符合的字母組合,加入list。等於是在迴圈中套遞迴
* 我的做法
*      超過99%的測試案例
*      時間複雜度:n2
*      空間複雜度:n
* 程式碼執行過程:
*
* 總結:
*      沒有用遞迴的方式,直接使用迭代的方法
*
*
* ***********************************/
public List<String> letterCombinations(String digits) {

if (digits.length() == 0) {
    return Collections.EMPTY_LIST;
}

Map<Character, String> map = new HashMap<>();
map.put('2', "abc");
map.put('3', "def");
map.put('4', "ghi");
map.put('5', "jkl");
map.put('6', "mno");
map.put('7', "pqrs");
map.put('8', "tuv");
map.put('9', "wxyz");

char[] chars = digits.toCharArray();
List<String> result = new ArrayList<>();
result.add("");

for (char c : chars) {
    List<String> tmpList = new ArrayList<>();
    String sufStr = map.get(c);
    for (String str : result) {
        for (Character tmpC : sufStr.toCharArray()) {
            String tmpStr = str + tmpC;
            tmpList.add(tmpStr);
        }
    }
    result = tmpList;
}

return result;
} 

大佬們的答案

/**************************************
 * 比我好的答案 better
 * ***********************************/
public List<String> better(String digits) {
    List<String> res = new ArrayList<>();
    String oneRes = "";
    if (digits.equals("")) {
        return res;
    }
    String[] dict = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
    int[] digiInt = new int[digits.length()];
    for (int i = 0; i < digits.length(); i++) {
        digiInt[i] = digits.charAt(i) - '0';
    }

    combi(digiInt, 0, dict, res, oneRes);
    return res;
}

public void combi(int[] digits, int n, String[] dict, List<String> res, String oneRes) {
    if (n == digits.length) {
        res.add(oneRes);
        return;
    }
    for (int j = 0; j < dict[digits[n]].length(); j++) {
        oneRes = oneRes + dict[digits[n]].charAt(j);
        combi(digits, n + 1, dict, res, oneRes);
        oneRes = oneRes.substring(0, oneRes.length() - 1);
    }
}

測試用例

@Test
public void test017() {
    // 建立測試案例
    String str1 = "23";

    // 測試案例期望值
    String[] strings = new String[] { "ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf" };
    List<String> expResult1 = Arrays.asList(strings);
    //        expResult1.addAll(strings);

    // 執行方法
    Solution017 solution017 = new Solution017();
    List<String> result1 = solution017.letterCombinations(str1);
    List<String> result11 = solution017.better(str1);

    // 判斷期望值與實際值
    Assert.assertEquals(expResult1, result1);
    Assert.assertEquals(expResult1, result11);

}

其他

“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改

如有疑問請聯絡,聯絡方式:QQ3060507060