leetcode 756. 金字塔转换矩阵 中等

你正在把积木堆成金字塔。每个块都有一个颜色,用一个字母表示。每一行的块比它下面的行 少一个块 ,并且居中。

为了使金字塔美观,只有特定的 三角形图案 是允许的。一个三角形的图案由 两个块 和叠在上面的 单个块 组成。模式是以三个字母字符串的列表形式 allowed 给出的,其中模式的前两个字符分别表示左右底部块,第三个字符表示顶部块。

  • 例如,"ABC" 表示一个三角形图案,其中一个 "C" 块堆叠在一个 'A' 块(左)和一个 'B' 块(右)之上。请注意,这与 "BAC" 不同,"B" 在左下角,"A" 在右下角。

你从作为单个字符串给出的底部的一排积木 bottom 开始,必须 将其作为金字塔的底部。

在给定 bottomallowed 的情况下,如果你能一直构建到金字塔顶部,使金字塔中的 每个三角形图案 都是在 allowed 中的,则返回 true ,否则返回 false

示例 1:

复制代码
输入:bottom = "BCD", allowed = ["BCC","CDE","CEA","FFF"]
输出:true
解释:允许的三角形图案显示在右边。
从最底层(第 3 层)开始,我们可以在第 2 层构建“CE”,然后在第 1 层构建“E”。
金字塔中有三种三角形图案,分别是 “BCC”、“CDE” 和 “CEA”。都是允许的。

示例 2:

复制代码
输入:bottom = "AAAA", allowed = ["AAB","AAC","BCD","BBE","DEF"]
输出:false
解释:允许的三角形图案显示在右边。
从最底层(即第 4 层)开始,创造第 3 层有多种方法,但如果尝试所有可能性,你便会在创造第 1 层前陷入困境。

提示:

  • 2 <= bottom.length <= 6
  • 0 <= allowed.length <= 216
  • allowed[i].length == 3
  • 所有输入字符串中的字母来自集合 {'A', 'B', 'C', 'D', 'E', 'F'}
  • allowed 中所有值都是 唯一的

分析:按照从下往上,从左向右的顺序,依次填三角形的每一个位置,对每个位置都进行 DFS,枚举所有可能填的字母。注意有部分底层的两个字母是不能填完整个三角形的,因此进行 DFS 的时候,可以先检查底层的两个字母是不是可以填完,如果不能填完,则直接返回 false。

cpp 复制代码
class Solution {
public:
    char pyramid[10][10],allow[10][10][10];
    bool ans=false;
    map<string,int>refuse;

    bool dfs(int x,int y,int level)
    {
        bool flag=false;

        for(int i=1;i<=6;++i)
        {
            int ind_x=pyramid[x+1][y]-'A'+1,ind_y=pyramid[x+1][y+1]-'A'+1;
            // 下一行的两个无法凑出三角形,记录这个不能凑,并返回false
            if(allow[ind_x][ind_y][0]==0)
            {
                string temp="";temp+=pyramid[x+1][y];temp+=pyramid[x+1][y+1];refuse[temp]=1;
                // printf("level=%d x=%d y=%d ",level,x,y);
                cout<<temp<<endl;
                return false;
            }
            // 下一行的两个可以凑,进行dfs
            if(allow[ind_x][ind_y][i])
            {
                pyramid[x][y]='A'+i-1;
                if(y>=2)
                {
                    string temp="";
                    temp+=pyramid[x][y-1];
                    temp+=pyramid[x][y];
                    if(refuse[temp])return false;
                }
                // 这一行已经填完了
                if(y==level)
                {
                    // 填完了第一行
                    if(level==1)return true;
                    // 填完的不是第一行,继续填上一行
                    else flag=dfs(x-1,1,level-1);
                }
                // 继续填下一个
                else flag=dfs(x,y+1,level);
                if(flag==true)return true;
            }
        }
        return flag;
    }

    bool pyramidTransition(string bottom, vector<string>& allowed) {
        bool flag=true;
        int n=allowed.size(),len=bottom.size();
        for(int i=0;i<n;++i)
        {
            int x=allowed[i][0]-'A'+1,y=allowed[i][1]-'A'+1,z=allowed[i][2]-'A'+1;
            allow[x][y][z]=1,allow[x][y][0]++;
        }
        for(int i=0;i<len;++i)
            pyramid[len][i+1]=bottom[i];

        flag=dfs(len-1,1,len-1);
        return flag;
    }
};
相关推荐
努力学算法的蒟蒻1 天前
day79(2.7)——leetcode面试经典150
算法·leetcode·职场和发展
2401_841495641 天前
【LeetCode刷题】二叉树的层序遍历
数据结构·python·算法·leetcode·二叉树··队列
2401_841495641 天前
【LeetCode刷题】二叉树的直径
数据结构·python·算法·leetcode·二叉树··递归
我是咸鱼不闲呀1 天前
力扣Hot100系列19(Java)——[动态规划]总结(上)(爬楼梯,杨辉三角,打家劫舍,完全平方数,零钱兑换)
java·leetcode·动态规划
铉铉这波能秀1 天前
LeetCode Hot100数据结构背景知识之列表(List)Python2026新版
数据结构·leetcode·list
仟濹1 天前
算法打卡 day1 (2026-02-06 周四) | 算法: DFS | 1_卡码网98 可达路径 | 2_力扣797_所有可能的路径
算法·leetcode·深度优先
YuTaoShao1 天前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法一)前后缀分解
算法·leetcode·职场和发展
VT.馒头1 天前
【力扣】2727. 判断对象是否为空
javascript·数据结构·算法·leetcode·职场和发展
老鼠只爱大米1 天前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
im_AMBER1 天前
Leetcode 114 链表中的下一个更大节点 | 删除排序链表中的重复元素 II
算法·leetcode