ARTS習慣(4)
米羅說
-
幹難事必有所得
-
捨近求遠,不珍惜身邊已有的做法是愚蠢的
-
光說不練,假把式;光練不說,傻把式
Algorithm
每週至少做一個Leetcode演算法題
【題目來源】
求最大子矩陣大小,左程雲《程式設計師程式碼面試指南:IT名企演算法與資料結構題目最優解(第2版)》
【題目】
給定一個整型矩陣map,其中的值只有0和1兩種,求其中全是1的所有矩形區域中,最大的矩形區域為1的數量。
【例子】
// 全是1的最大矩形包含3個1 1 1 1 0 // 矩陣1 ,全是1的最大矩形有6個1 1 0 1 1 1 1 1 1 1 1 1 0
【解答】
步驟1:建立height陣列。我們以【例子】的矩陣1為例,height陣列表示:逐行切割矩陣,以切割的行做為底,統計每列的連續1的個數。切割矩陣第一行時,height = {1,0,1,1},切割矩陣第二行時,height = {2,1,2,2,2},切割矩陣第三行時,height = {3,2,3,0}
步驟2:單調棧求每列最大能左右擴多大。 以height = {3,4,5,4,3,6}為例說明,
1.生成棧stack存放height陣列的索引位置,從左至右遍歷height陣列
2.棧的壓入規則:棧單調遞減,遍歷到當前值height[i]時,height[i]>height[stack.peek()]
3.棧的彈出規則:height[i]<=height[stack.peek()]時,彈出棧頂位置,直到滿足壓入規則,即height[i]>height[stack.peek()]
4.最大矩形:j位置的最大矩形為(i-k-1)*height[j],注:j:當前彈出的棧頂位置,i:當前位置,k:彈出棧頂j後,新的棧頂。證明見求最大子矩陣大小
參考程式碼如下:
package com.pengluo.zcy_algorithm; import java.util.Stack; public class A16_MaxRecSize { public static int maxRecSize(int[][] map) { if (map == null || map[0].length ==0 || map.length == 0) { return 0; } int[] height = new int[map[0].length]; int maxSize = 0; for (int i = 0; i < map.length; i++) { for (int j = 0; j < map[0].length; j++) { height[j] = map[i][j] == 0 ? 0 : height[j] + 1; } // 逐行切割,重新整理最大值 maxSize = Math.max(maxRecFromBottom(height), maxSize); } return maxSize; } public static int maxRecFromBottom(int[] height) { if (height.length == 0 || height ==null){ return 0; } int maxArea = 0; Stack<Integer> stack = new Stack<Integer>(); for (int i = 0; i < height.length; i++) { while(!stack.isEmpty() && height[stack.peek()]>height[i]) { int j = stack.pop(); int k = stack.isEmpty() ? -1 : stack.peek(); int curArea = (i - k - 1 ) * height[j]; maxArea = Math.max(curArea, maxArea); } stack.push(i); } while(!stack.isEmpty()) { int j = stack.pop(); int k = stack.isEmpty() ? -1 : stack.peek(); int curArea = (height.length - k - 1) * height[j]; } return maxArea; } public static void main(String[] args) { int[][] map = {{1,0,1,1},{1,1,1,1},{1,1,1,0}}; System.out.println(maxRecSize(map)); } }
【思考討論】
- 思考公式(i-k-1)*height[j]的推導
Review
閱讀並點評至少1篇英文技術文章
【原文】:Head First Java(2nd Editon)CH8 Serious Polymorphism
【譯文】:英文版原汁原味,語義準確,本書的寫作風格幽默,容易理解。讀者應重點關注作者是如何一步一步帶你帶你分析問題的,不必糾結細枝末節的東西。讀者也可移步Head First Java(第二版·中文版)。
【點評】:
多型主題圍繞:繼承父類和實現介面展開,看完本章後豁然開朗,一些模稜兩可的概念一下就清晰了。
-
The compiler won’t let you instantiate an abstract class(抽象類不能例項化)
-
An abstract method has no body! (抽象方法沒有{},分號結尾,需要在具體類中override)
abstract public class Dog { abstract public void eat(); }
-
Every class in Java extends class Object(Java中任何類直接或間接的都繼承Object)
-
multiple inheritance has Deadly Diamond of Death(Java不允許多繼承,死亡菱形)
-
A Java interface is like a 100% pure abstract class.(介面是百分百的抽象類,Java允許實現多個介面)
-
Polymorphism(多型)
-
多使用抽象的父類做方法引數、返回型別、陣列 賦值
abstract public class Animal {} public Dog extends Animal {} public Cat extends Animal {} // 陣列 Animal[] animals = new Animal[3]; animals[0] = new Dog(); animals[1] = new Cat(); // 方法入參 public void add(Animal a) { }
-
強轉型別之前,instanceof 判斷型別
if (d instanceof Dog) { Dog dog = (Dog) }
-
-
2個常見介面
// save state to a file
public class Dog implements Serializable
// run its method in a separate thread of execution
public class Dog implements Runnable
Tip
學習至少一個技術技巧
參考我之前寫的一篇Mybatis逆向工程生成程式碼的部落格。自動化配置(1):利用Mybatis-generator自動生成實體類,介面,mapper.xml
Share
分享一篇有觀點和思考的技術文章
分享極客時間上的一個演算法專欄,谷歌演算法工程師主講的,資料結構和演算法之美
目前已突破10W訂閱,乾貨很多,能堅持跟下來會很有收穫的。