来源:LeetCode 第17题【公众号:数据结构和算法】
示例1:
输入:d i g i t s = " 2 3 "
输出:[" a d "," a e "," a f"," b d "," b e "," b f"," cd "," ce "," c f"]示例2:
输入:d i g i t s = ""
输出:[ ] 示例3:
输入:d i g i t s = " 2 "
输出:[" a "," b "," c "]
提示:
● 0<=digits.length<=4
● digits[]是范围['2' , '9']的一个数字。
每一个数字对应3到4个字符,我们以示例一为例画个图来看一下
我们看到实际上就是一颗n叉树,除了叶子节点外,每个节点都有3到4个子节点。对于二叉树的BFS遍历如下图所示,也就是一行一行的访问 。
public void levelOrder(TreeNode tree) { //链表,这里我们可以把它看做队列 LinkedList list = new LinkedList<>(); list.add(tree);//相当于把数据加入到队列尾部 while (!list.isEmpty()) { //poll方法相当于移除队列头部的元素 TreeNode node = list.poll(); //访问当前节点 System.out.println(node.val); //遍历当前节点的左子节点和右子节点 if (node.left != null) list.add(node.left);if (node.right != null) list.add(node.right); }
}
public void levelOrder(TreeNode tree) { //链表,这里我们可以把它看做队列 LinkedList list = new LinkedList<>(); list.add(tree);//相当于把数据加入到队列尾部 while (!list.isEmpty()) { //poll方法相当于移除队列头部的元素 TreeNode node = list.poll(); //访问当前节点 System.out.println(node.val); //遍历当前节点的所有子节点 for (int i = 0; i < node.child.count; i++) { list.add(node.child[i]); } }
}
//BFS
public List letterCombinations(String digits) { LinkedList res = new LinkedList<>(); //空判断 if (digits == null || digits.isEmpty()) return res; char[][] tab = {{'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}, {'j', 'k', 'l'}, {'m', 'n', 'o'}, {'p', 'q', 'r', 's'}, {'t', 'u', 'v'}, {'w', 'x', 'y', 'z'}}; res.add(""); while (res.peek().length() != digits.length()) {String remove = res.poll();//出队 char[] chars = tab[digits.charAt(remove.length()) - '2']; //相当于当前节点的所有子节点 for (int i = 0; i < chars.length; i++) { res.add(remove + chars[i]);//入队 } } return res;
}
public List letterCombinations(String digits) { List res = new ArrayList<>(); if (digits == null || digits.isEmpty()) return res; char[][] tab = {{'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}, {'j', 'k', 'l'}, {'m', 'n', 'o'}, {'p', 'q', 'r', 's'}, {'t', 'u', 'v'}, {'w', 'x', 'y', 'z'}}; dfs(res, 0, digits, tab, ""); return res;
} /**
* @param res
* @param index 表示访问到第几个数字了,也可以认为访问到树的第几层了
* @param digits
* @param tab
* @param path 从根节点到叶子结点的路径
*/ private void dfs(List res, int index, String digits, char[][] tab, String path) { //到叶子节点了,就把这条路径选择的字符添加到res中 if (path.length() == digits.length()) { res.add(path);return; } char[] chars = tab[digits.charAt(index) - '2']; //访问当前节点的所有子节点 for (int i = 0; i < chars.length; i++) { dfs(res, index + 1, digits, tab, path + chars[i]); //因为字符串是创建了一个新的对象,所以这里不需要撤销 }
}