LeetCode - Medium - 17. Letter Combinations of a Phone Number

这篇博客介绍了如何使用Java实现电话号码对应的字母组合。作者给出了三种不同的方法,包括两种广度优先搜索(BFS)实现和一种深度优先搜索(DFS,也称回溯算法)实现。每种方法都详细地展示了代码实现,并通过测试用例验证了正确性。博客内容涉及到字符串处理、算法设计和递归技术。
摘要由CSDN通过智能技术生成

Topic

  • String
  • Backtracking
  • Depth-first Search
  • Breadth-first Search
  • Recursion

Description

https://leetcode.com/problems/letter-combinations-of-a-phone-number/

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

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 1:

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

Example 2:

Input: digits = ""
Output: []

Example 3:

Input: digits = "2"
Output: ["a","b","c"]

Constraints:

  • 0 <= digits.length <= 4
  • digits[i] is a digit in the range [‘2’, ‘9’].

Analysis

方法一:我写的BFS

方法二:别人A写的BFS

方法三:别人B写的DFS(或称回溯算法)

Submission

import java.util.LinkedList;
import java.util.List;

public class LetterCombinationsOfAPhoneNumber {

	// 方法一:我写的BFS
	public static final String[] num2Letters = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };

	public List<String> letterCombinations1(String digits) {
		List<String> result = new LinkedList<>();
		if (digits == null || digits.trim().length() == 0)
			return result;
		result.add("");

		for (int i = 0; i < digits.length(); i++)
			letterCombinations(result, digits.charAt(i) - '0');

		return result;
	}

	private void letterCombinations(List<String> result, int num) {
		int originalResultSize = result.size();
		String[] letters = num2Letters[num].split("");
		for (int i = 0; i < originalResultSize; i++) {
			String temp = result.remove(0);
			for (int j = 0; j < letters.length; j++) {
				StringBuilder sb = new StringBuilder();
				sb.append(temp);
				sb.append(letters[j]);
				result.add(sb.toString());
			}
		}
	}

	// 方法二:别人A写的BFS
	public List<String> letterCombinations2_1(String digits) {
		LinkedList<String> ans = new LinkedList<String>();
		if (digits.isEmpty())
			return ans;
		String[] mapping = new String[] { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
		ans.add("");
		for (int i = 0; i < digits.length(); i++) {
			int x = Character.getNumericValue(digits.charAt(i));
			while (ans.peek().length() == i) {
				String t = ans.remove();
				for (char s : mapping[x].toCharArray())
					ans.add(t + s);
			}
		}
		return ans;
	}

	// 方法二:别人A写的(第二版)BFS
	public List<String> letterCombinations2_2(String digits) {
		LinkedList<String> ans = new LinkedList<String>();
		if (digits.isEmpty())
			return ans;
		String[] mapping = new String[] { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
		ans.add("");
		while (ans.peek().length() != digits.length()) {
			String remove = ans.remove();
			String map = mapping[digits.charAt(remove.length()) - '0'];
			for (char c : map.toCharArray()) {
				ans.addLast(remove + c);
			}
		}
		return ans;
	}

	// 方法三:别人B写的 DFS 递归
	private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };

	public List<String> letterCombinations3(String digits) {
		List<String> ret = new LinkedList<String>();
		if (digits == null || digits.length() == 0)
			return ret;
		combination("", digits, 0, ret);
		return ret;
	}

	private void combination(String prefix, String digits, int offset, List<String> ret) {
		if (offset >= digits.length()) {
			ret.add(prefix);
			return;
		}
		String letters = KEYS[(digits.charAt(offset) - '0')];
		for (int i = 0; i < letters.length(); i++) {
			combination(prefix + letters.charAt(i), digits, offset + 1, ret);
		}
	}

}

Test

import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import org.junit.Test;
import org.hamcrest.collection.IsEmptyCollection;

public class LetterCombinationsOfAPhoneNumberTest {

	@Test
	public void test() {
		LetterCombinationsOfAPhoneNumber obj = new LetterCombinationsOfAPhoneNumber();

		assertThat(obj.letterCombinations1("23"),
				containsInAnyOrder("ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"));
		assertThat(obj.letterCombinations1(""), IsEmptyCollection.empty());
		assertThat(obj.letterCombinations1("2"), containsInAnyOrder("a", "b", "c"));

		assertThat(obj.letterCombinations2_1("23"),
				containsInAnyOrder("ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"));
		assertThat(obj.letterCombinations2_1(""), IsEmptyCollection.empty());
		assertThat(obj.letterCombinations2_1("2"), containsInAnyOrder("a", "b", "c"));

		assertThat(obj.letterCombinations2_2("23"),
				containsInAnyOrder("ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"));
		assertThat(obj.letterCombinations2_2(""), IsEmptyCollection.empty());
		assertThat(obj.letterCombinations2_2("2"), containsInAnyOrder("a", "b", "c"));

		assertThat(obj.letterCombinations3("23"),
				containsInAnyOrder("ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"));
		assertThat(obj.letterCombinations3(""), IsEmptyCollection.empty());
		assertThat(obj.letterCombinations3("2"), containsInAnyOrder("a", "b", "c"));
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值