227、金字塔转换矩阵

题目描述:
现在,我们用一些方块来堆砌一个金字塔。 每个方块用仅包含一个字母的字符串表示,例如 “Z”。

使用三元组表示金字塔的堆砌规则如下:

(A, B, C) 表示,“C”为顶层方块,方块“A”、“B”分别作为方块“C”下一层的的左、右子块。当且仅当(A, B, C)是被允许的三元组,我们才可以将其堆砌上。

初始时,给定金字塔的基层 bottom,用一个字符串表示。一个允许的三元组列表 allowed,每个三元组用一个长度为 3 的字符串表示。

如果可以由基层一直堆到塔尖返回true,否则返回false。

示例 1:

输入: bottom = “XYZ”, allowed = [“XYD”, “YZE”, “DEA”, “FFF”]
输出: true
解析:
可以堆砌成这样的金字塔:
A
/
D E
/ \ /
X Y Z

因为符合(‘X’, ‘Y’, ‘D’), (‘Y’, ‘Z’, ‘E’) 和 (‘D’, ‘E’, ‘A’) 三种规则。
示例 2:

输入: bottom = “XXYX”, allowed = [“XXX”, “XXY”, “XYX”, “XYY”, “YXZ”]
输出: false
解析:
无法一直堆到塔尖。
注意, 允许存在三元组(A, B, C)和 (A, B, D) ,其中 C != D.
注意:

bottom 的长度范围在 [2, 8]。
allowed 的长度范围在[0, 200]。
方块的标记字母范围为{‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’}。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pyramid-transition-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

递归+回溯+DFS
使用map保存

class Solution {
    private Map<String, List<Character>> map;
    public boolean pyramidTransition(String bottom, List<String> allowed) {
        /**
        直接暴力搜索的dfs会超时, 要利用一个map保存所有方块可能的顶部字母
        **/
        map = new HashMap<>();
        for(String brick : allowed) {
            String base = brick.substring(0, 2);
            if(!map.containsKey(base))
                map.put(base, new ArrayList<>());
            map.get(base).add(brick.charAt(2));
        }
        return dfs(bottom);
    }
    private boolean dfs(String bottom) {
        // bottom为1说明到达金字塔顶端, 可以搭成金字塔
        if(bottom.length() == 1) 
            return true;
        // 如果bottom中有未出现过的方块底层说明不能搭成金字塔
        for(int i = 0; i < bottom.length()-1; ++i)
            if(!map.containsKey(bottom.substring(i,i+2)))
                return false;
        // 根据bottom生成所有可能的上层方块
        List<String> candidates = new ArrayList<>();
        generateUpper(bottom, candidates, new StringBuilder(), 0);
        for(String upper : candidates)
            if(dfs(upper))
                return true;
        return false;
    }
    
    private void generateUpper(String bottom, List<String> candidates, StringBuilder sb, int st) {
        if(st == bottom.length()-1) {
            candidates.add(sb.toString());
            return;
        }
        for(Character c : map.get(bottom.substring(st, st+2))) {
            sb.append(c);
            generateUpper(bottom, candidates, sb, st+1);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}

自己尝试实现一遍

class Solution {
    Map<String, List<Character>> map = new HashMap<>();
	public boolean pyramidTransition(String bottom, List<String> allowed) {
		for (String string : allowed) {
			String tem = string.substring(0,2);
			if(map.get(tem) == null){
				map.put(tem, new ArrayList<Character>());
			}
			map.get(tem).add(string.charAt(2));
		}
        return dfs1(bottom);
	}
//	获取到所有的可能的底层
	public boolean dfs1(String botom){
		if(botom.length() == 1){
			return true;
		}
        for (int i = 0; i < botom.length() - 1; ++i)
			if (!map.containsKey(botom.substring(i, i + 2)))
				return false;
//		获取到所有的上层建筑
		List<String> list = new ArrayList<>();
		getupper(list, botom, 0, new StringBuilder());
		for (String string : list) {
			if(dfs1(string)){
				return true;
			}
		}
		return false;
	}
	public void getupper(List<String> list,String botom,int index,StringBuilder sb){
		if(index == botom.length() - 1){
			list.add(sb.toString());
			return ;
		}
		for (Character temchar : map.get(botom.substring(index,index + 2))) {
			sb.append(temchar);
			getupper(list, botom, index + 1, sb);
			sb.deleteCharAt(sb.length() -1);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值