leetcode之回溯backtracing专题3

17 Letter Combinations of a Phone Number

 手机上每个数字按钮旁边都有3-4个字母,输入数字字符串,输出可能的字母组合。
 例如输入:”23”
 输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
 思路:建立每个数字和对应字母的映射关系。该个处理每一位数字,遍历每个数字可能的取值。按照递归去实现很简单。
 

private  List<String> result = new ArrayList<String>();
private static Map<Integer, List<Character>> numberMap = new HashMap<Integer, List<Character>>();
static{
    for(int i=2;i<7;i++){
        numberMap.put(i, new ArrayList<Character>());
        for (int j = 0; j < 3; j++) {
            char ch = (char) ('a' + 3 * (i - 2) + j);
            numberMap.get(i).add(ch);
        }

    }
    numberMap.put(7, new ArrayList<Character>());
    numberMap.get(7).add('p');
    numberMap.get(7).add('q');
    numberMap.get(7).add('r');
    numberMap.get(7).add('s');
    numberMap.put(8, new ArrayList<Character>());
    numberMap.get(8).add('t');
    numberMap.get(8).add('u');
    numberMap.get(8).add('v');
    numberMap.put(9, new ArrayList<Character>());
    numberMap.get(9).add('w');
    numberMap.get(9).add('x');
    numberMap.get(9).add('y');
    numberMap.get(9).add('z');

}
public List<String> letterCombinations(String digits) {
    result.clear();
    StringBuilder str = new StringBuilder(digits.length());
    str.setLength(digits.length());
    if(digits.length()>0){
        robot(0, digits, str);
    }
    return result;
}



private void robot(int idx, String digits, StringBuilder r) {
    if (idx >= digits.length()) {
        result.add(r.toString());
        return;
    }
    int n = digits.charAt(idx) - 48;
    if (n < 2)
        return;
    for(char ch : numberMap.get(n)){
        r.setCharAt(idx, ch);
        robot(idx + 1, digits, r);
    }
}

收获1

 嗯代码够丑的。看别人怎么处理映射关系。我怎么没想到呢。之前也有这样一个例子,当数字作为map的key的时候,选择用数组代替map,可能会是一种比较优雅的方式。
 

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

收获2

 一次性给stringBuider 一定的长度。这个做法在字符串中还是有点变扭。这个想法是从数组那里继承过来的。可以使用字符串相加的方式。
 

private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
private List<String> result = new ArrayList<String>();

public List<String> letterCombinations(String digits) {
    result.clear();
    robot(0, digits, "");
    return result;
}

private void robot(int idx, String digits, String prefix) {
    if (idx >= digits.length()) {
        if (prefix.length() > 0) {
            result.add(prefix);
        }

        return;
    }
    int n = digits.charAt(idx) - 48;
    if (n < 2)
        return;
    String letters = KEYS[n];
    for (int i = 0; i < letters.length(); i++) {
        robot(idx + 1, digits, prefix + letters.charAt(i));
    }
}

收获3

 我是没法用递推的方式实现的,只能用递归。看看别人怎么做。其实从上一个递归的代码是可以得到一些启示的。当然这是“马后炮”的想法–看到别人这么做觉得应该想到的。但是之前我一直在用for去思考。
 

public List<String> letterCombinations(String digits) {
        LinkedList<String> ans = new LinkedList<String>();
        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;
    }

参考链接
1 链接1 
2 链接2

内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了最小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初次下载时IP地址的设置方法。最后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成最小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值