這是我參與更文挑戰的第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