这是我参与更文挑战的第18天,活动详情查看: 更文挑战java
给你一个奇怪的打印机,它有以下两个特殊的打印规则:算法
每一次操做时,打印机会用同一种颜色打印一个矩形的形状,每次打印会覆盖矩形对应格子里本来的颜色。 一旦矩形根据上面的规则使用了一种颜色,那么 相同的颜色不能再被使用 。 给你一个初始没有颜色的 m x n 的矩形
targetGrid
,其中targetGrid[row
][col] 是位置 (row, col) 的颜色。markdown若是你能按照上述规则打印出矩形
targetGrid
,请你返回 true ,不然返回 false 。oop
只有保持这个维度才能确保外部被打乱的颜色能够被打印机打印。由于打印机的两个特性:一次打印矩形+一个颜色只能用一次post
换句话说不通颜色咱们能够理解成不一样卡片叠加在一块儿产生的效果。最底层的就是咱们最外层的颜色。只有这样最小的最上层才会被从新渲染。spa
m*n
矩阵进行判断!既然是判断是否知足这个奇葩的打印机那就稍微简单一点。for (Map.Entry<Integer, Direction> entry : entries) {
Integer key = entry.getKey();
if (sameColorAndPrintMark(key, entry.getValue(), targetGrid)) {
value=key;
break;
}
}
复制代码
sameColorAndPrintMark
方法。该方法是判断区间内是否颜色相同并进行打印标记的。由于颜色取值是[1,60]。因此咱们这里使用0来标记已经被其余色块打印过 。而后在判断是不是同一色块时过滤掉已经被渲染色块在进行判断若是不经过则真的没法经过了。private boolean sameColorAndPrintMark(Integer key, Direction direction, int[][] targetGrid) {
for (int i = direction.top; i <= direction.bottom; i++) {
for (int j = direction.left; j <= direction.right; j++) {
if(targetGrid[i][j]!=0&&targetGrid[i][j]!=key)
return false;
}
}
for (int i = direction.top; i <= direction.bottom; i++) {
for (int j = direction.left; j <= direction.right; j++) {
targetGrid[i][j] = 0;
}
}
return true;
}
复制代码
if (value == -1) {
return false;
} else {
//剔除
colorMap.remove(value);
}
复制代码
class Direction{
int left = 61;
int right = -1;
int top = 61;
int bottom = -1;
}
public boolean isPrintable(int[][] targetGrid) {
int[] values=new int[61];
int n=targetGrid.length, m=targetGrid[0].length;
Map<Integer,Direction> colorMap = new HashMap<>();
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
int val=targetGrid[i][j];
Direction direction = null;
if (colorMap.containsKey(val)) {
direction = colorMap.get(val);
} else {
direction = new Direction();
colorMap.put(val,direction);
}
direction.left = Math.min(direction.left, j);
direction.right = Math.max(direction.right, j);
direction.top = Math.min(direction.top, i);
direction.bottom = Math.max(direction.bottom, i);
}
}
while (!isAllPrint(targetGrid)) {
int value=-1;
Set<Map.Entry<Integer, Direction>> entries = colorMap.entrySet();
for (Map.Entry<Integer, Direction> entry : entries) {
Integer key = entry.getKey();
if (sameColorAndPrintMark(key, entry.getValue(), targetGrid)) {
value=key;
break;
}
}
if (value == -1) {
return false;
} else {
//剔除
colorMap.remove(value);
}
}
return true;
}
private boolean isAllPrint(int[][] targetGrid) {
for (int i = 0; i < targetGrid.length; i++) {
for (int j = 0; j < targetGrid[i].length; j++) {
if (targetGrid[i][j]!=0) {
return false;
}
}
}
return true;
}
private boolean sameColorAndPrintMark(Integer key, Direction direction, int[][] targetGrid) {
for (int i = direction.top; i <= direction.bottom; i++) {
for (int j = direction.left; j <= direction.right; j++) {
if(targetGrid[i][j]!=0&&targetGrid[i][j]!=key)
return false;
}
}
for (int i = direction.top; i <= direction.bottom; i++) {
for (int j = direction.left; j <= direction.right; j++) {
targetGrid[i][j] = 0;
}
}
return true;
}
复制代码
此题比较有意思的是须要分层考虑打印问题!从外至内进行打印渲染。可是由于不肯定因素因此咱们一次渲染没法最终得出结果,因此须要咱们进行屡次渲染。调试
可是须要多少次咱们也没法肯定,这时候咱们就一直渲染!可是不能一直渲染因此咱们每次渲染后须要对是否须要继续下去进行断定code
固然笔者这里也不是一番风顺的,提交过程也是不断的试错调试。这里我只是想告诉读者们刷题须要不断努力,不要由于错误而放弃orm
这里点个赞、关个注呗!持续贡献原创文章!若是你以为那个算法有意思,下方告诉我,我去试试可否攻克!!!leetcode