Lettercode 17. Letter combinations of a phone number (Java)

Title:

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example:
Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.

Answer:

Solution 1: HashMap + multiple cycles

This problem only thought of violent solution.
That is to say, the letters corresponding to all numbers are taken out in turn through a loop, and then nested and traversed. With the help of HashMap, the key value relationship between numbers and letters is stored.

The idea of loop nesting is as follows:

  1. The first layer of loop: loop digits.length(), take out each input number in turn, and use the get() method in HashMap to take out the corresponding letter value substr
  2. Then the value corresponding to the next number is taken out, nested and combined.
    For example, the first number 2 corresponds to a b c. At this time, the value in the list array is [a,b,c]. Cycle the next number 3, corresponding to d E F, traverse the value in the list, respectively spell a,b,c with d, e, f, cycle in turn, and finally return the list
class Solution {
    public List<String> letterCombinations(String digits) {
        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");     
        List<String> list = new ArrayList<>();
        if(digits.length()==0) {
            return list;
        }
        list.add("");
        for(int i=0; i<digits.length(); i++) {
            List<String> temp = new ArrayList<>();
            String substr = map.get(digits.charAt(i));            
            for(String str: list) {
                for(int j=0; j<substr.length(); j++) {
                    String strsum = str + substr.charAt(j);
                    temp.add(strsum);
                }
            }
            list = temp;
        }
        return list;
    }
}

Solution 2: queue + cycle

Alternatively, the first in, first out nature of the queue can be used for horizontal combination
Train of thought:

  1. First, take the first number in the input, find the string it represents, traverse the letters and put them in the queue in turn
  2. Then take out the next input number, find the string it represents, queue out in turn, combine with each letter represented in the current string in turn, and enter the queue again
  3. When the length of all strings in the queue = = the length of the input string, all combinations are completed. Therefore, we can get the length of queue head element through res.peek().length(), and judge whether it is the same as digits.length()
    (so in the second step, you can get the next number of input through the length of characters in the queue.)
class Solution {
    public List<String> letterCombinations(String digits) {
        LinkedList<String> res = new LinkedList<>();
        String[] map = new String[] {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        if(digits.length()==0) {
            return res;
        }
        res.add("");
        while(res.peek().length() != digits.length()) {
            String temp = res.pop();
            String str = map[digits.charAt(temp.length()) - '0'];
            for(char c: str.toCharArray()) {
                res.add(temp + c);
            }
        }
        return res;
    }
}

The code of this method is simpler, but it is the same as the solution, so the time complexity is the same.

Solution 3: backtracking

"Backtracking" algorithm: it is a search attempt process similar to enumeration. It is mainly to find the solution of the problem in the search attempt process. When it is found that the solution conditions are not met, it will "backtrack" and try other paths. Backtracking is a search method of selecting the best, which searches forward according to the conditions of selecting the best to achieve the goal. However, when a certain step is explored, and it is found that the original choice is not good or fails to achieve the goal, it will go back one step and choose again.
Most backtracking problems depend on several elements: recursion, depth first, and Full Permutation

Analysis of the problem shows that the output approximation of the problem is to enumerate all permutations that meet the conditions. I.e. fix one position at a time and change other positions
If the input number is "234", then the first character has three choices, namely "a", "b", "c". If the first character selects a, then the second character also has three choices. After the second character is selected, the third character has three choices By analogy, it will be found that this logical thinking is very similar to the tree structure. Each layer has more than one child node.
Therefore, it can be solved by "backtracking".

class Solution {
    private static final String[] map = new String[] {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    public List<String> letterCombinations(String digits) {
        List<String> res = new ArrayList<>();        
        if(digits.length()==0) {
            return res;
        }
        doCombination(new StringBuffer(), res, digits);
        return res;
    }
    private void doCombination(StringBuffer str, List<String> res, String digits) {
    	//str reaches the expected length, i.e. once the combination is completed, str is saved in res
        if(str.length() == digits.length()) {
            res.add(str.toString());
            return;
        }
        //Read the optional character set corresponding to the element traversed by current digits
        String substr = map[digits.charAt(str.length())-'0'];
        //Traverse the optional character set, fix the character in the current position every time, and then select the next character
        for(char c: substr.toCharArray()) {
            str.append(c);  //Add to
            doCombination(str, res, digits);  // recursion
            str.deleteCharAt(str.length() - 1);  //delete
        }
    }
}
Published 89 original articles, won praise 3, visited 1348
Private letter follow

Posted on Mon, 16 Mar 2020 08:37:43 -0400 by lemist