Search - 17 - BFS/DFS

Letter Combinations or a Phone Number
在这里插入图片描述
分析:

  • 用graph search来做,BFS/DFS,adjacency matrix
  • adajacency matrix时间复杂度之前是O(n2),因为2是重复次数。n是节点数也就是一次里有多少种可能性。在这道题里呢,包含2-9的字符串,所以最多重复8次,每次有最多4个字母的可能性,也就是O (4n),n is the length of the input.
  • 在这里插入图片描述

DFS

  • 当题目中出现所有符合题目的解搜索算法进行解题
  • 自顶向下的递归实现深搜
  • 定义子问题,如果是tree就是对子树,如果字符串就是substring,剩余字符串的问题
  • 在当前递归层结合子问题解决原问题

数组是键值为非负整数的散列表。

class Solution {

    public List<String> letterCombinations(String digits) {
        // 定义返回值
        List<String> result = new ArrayList<String>();
        // check if the input is empty
        if(digits.length() == 0){
            return result;
        }

        // if input is not empty
        // 定义电话号码和字母的映射 - 多种方法
        // HashMap - Java单双引号的区别
        Map<Character,String> phoneBook = new HashMap<Character,String>(){{
            put('2',"abc");
            put('3',"def");
            put('4',"ghi");
            put('5',"jkl");
            put('6',"mno");
            put('7',"pqrs");
            put('8',"tuv");
            put('9',"wxyz");
        }};
        // 第二种方法: String[]
        // String[] phoneBook = new String[]{"", "", "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};


        //input not empty: implement DFS algorithm
        dfs(phoneBook, digits, 0, result, new StringBuilder());
        return result;
    }

    private void dfs(Map<Character,String> phoneBook, String digits, int index, List<String> result, StringBuilder sb){
        //check boundary condition
        // when the DFS ends
        if(index == digits.length()){
            // 把Stringbuilder的值传回给result
            result.add(sb.toString());
            return;
        }

        // 首先根据phoneBook根据数字得到映射的字母字符串
        String letters = phoneBook.get(digits.charAt(index));
        // String letters = phoneBook(Character.getNumericValue(digits.charAt(index))) - 如果是String[] phoneBook

        // 遍历每个字母
        for (int i = 0; i < letters.length(); i++){
            // 首先加到sb里
            sb.append(letters.charAt(i));
            // 继续向下implement DFS
            dfs(phoneBook, digits, index + 1, result, sb);
            // 每次dfs结束后清除sb最后一位
            sb.deleteCharAt(index);
        }
    }
}
  • 分析时间复杂度
    对于每次输入,最坏的可能性是每个数字对应4个字母。一共有n次输入,n is the length of the input, time complexity takes O(4n)
  • Space Complexity
    space为递归的stack space。因为有n个stack所以递归的时候有n层。O(n + 4n).
  • 做题总结:像这样DFS是每一次把参数加到结果里最后返回一个conbinations的情况,并不需要dfs有返回值,void就可以。

BFS

BFS是逐层递归,对于这道题,先遍历2的字母"abc"再3 - “def” = [(a,b,c)] x [(d,e,f)]

  • Time Complexity: O(4n)
  • Space Complexity: O(4n)
class Solution {

    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<String>();
        if(digits.length() == 0){return result;}

        String[] phoneBook = new String[]{"", "", "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

        // 先给result添加空字符串
        result.add("");
        // 对于数字字符串里的每个数字 - 把String转化为charArray
        for (char digit: digits.toCharArray()){
            // 构造一个新的临时数组变量, 储存第i+1层
            List<String> tmp = new ArrayList<String>();
            for (String s: result){ //初始状态为空,空字符串也可以被遍历到
                //储存目前这一位数字所对应字母string
                String str = phoneBook[Character.getNumericValue(digit)];
                for(int i = 0; i < str.length(); i++){
                    tmp.add(s+str.charAt(i));  //这时候tmp=[a,b,c]
                }
            }
            result = tmp;
        }
    return result; 
    }
}

从这道题里学到的事

  1. 有关char的运用
  • String和Char之数组间的转换:String[].toCharArray()
  • String得到第i位的具体char:String.charAt(i)
  • String删除第i位char: String.deleteCharAt(i)
  • Char -> int: Character.getNumericValue(char)
  1. Java单双引号有区别
  • 单引号包括char值
  • 双引号包含String值
  1. StringBuilder和StringBuffer是String的同伴类,可以随意增添修改字符串
  • StringBuilder不是线程安全的
  • StringBuffer是线程安全的
  1. if - else另种写法
if condition:
	do A
else if:
	do B

if condition:
	do A
	return
do B
  1. 在每个函数前面应该首先考虑边界条件
  2. 针对这道题,DFS比BFS快,储存phoneMap,HashMap比String[]快
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值