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;
    }
};
相关推荐
evans在进步2 小时前
LeetCode 438 找到字符串中所有字母异位词:滑动窗口与排序解法详解
算法·leetcode·职场和发展
码行山野赴时序归途2 小时前
从暴力到最优:三道 C 语言入门题的解法思路
c语言·开发语言·数据结构·算法·leetcode·排序算法
土司大王2 小时前
LeetCode hot100——随机链表的复制
算法·leetcode·链表
Tisfy4 小时前
LeetCode 3720.大于目标字符串的最小字典序排列:状态机 —— :从左往右枚举,失败则退回(最多退回一次)
linux·数据库·leetcode·字符串·状态机·构造
土司大王7 小时前
LeetCode hot100——二叉树的最大深度
算法·leetcode·职场和发展
圣保罗的大教堂7 小时前
leetcode 3720. 大于目标字符串的最小字典序排列 中等
leetcode
Tisfy13 小时前
LeetCode 1927.求和游戏:抵消+看最值
java·leetcode·游戏·题解·博弈论
玖玥拾13 小时前
LeetCode 125 验证回文串
算法·leetcode
玖玥拾1 天前
LeetCode 392 判断子序列
笔记·算法·leetcode
重生之后端学习1 天前
239. 滑动窗口最大值[困难]✅
java·数据结构·算法·leetcode·职场和发展