import java.util.*; /** * NC388 砖墙的垂线 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 画砖墙图 -> 一目了然 * * "如果你画的线只是从砖块边缘经过则不算是经过。" -> 尽量从边缘经过, 垂线才能最少经过砖块! * * @param wall int整型二维数组 * @return int整型 */ public int brickwall (ArrayList<ArrayList<Integer>> wall) { // return solution1(wall); return solution2(wall); } /** * 哈希: cnt[] * @param wall * @return */ private int solution1(ArrayList<ArrayList<Integer>> wall){ // 砖墙行数 int n = wall.size(); // 砖墙最右边缘 int rightmost = 0; for(int width: wall.get(0)){ rightmost += width; } // 边缘统计 int[] cnt = new int[rightmost]; // 每行砖块 ArrayList<Integer> bricks; // 砖块边缘 int edge; // 相同砖块边缘统计 取最大值 int max = 0; for(int i=0; i<n; i++){ bricks = wall.get(i); edge = 0; for(int width: bricks){ edge += width; if(edge < rightmost){ cnt[edge]++; max = Math.max(max, cnt[edge]); } } } // 砖墙行数-最大值 return n-max; } /** * 哈希: cntMap * @param wall * @return */ private int solution2(ArrayList<ArrayList<Integer>> wall){ // 砖墙行数 int n = wall.size(); // 边缘统计 HashMap<Integer,Integer> cntMap = new HashMap<>(); // 每行砖块 ArrayList<Integer> bricks; // 砖块边缘 int edge; // 相同砖块边缘统计 取最大值 int max = 0; for(int i=0; i<n; i++){ bricks = wall.get(i); edge = 0; // 减1 排除砖墙最右边缘rightmost for(int j=0; j<bricks.size()-1; j++){ // 当前砖块边缘(右)+砖块宽度 edge += bricks.get(j); cntMap.put(edge, cntMap.getOrDefault(edge,0)+1); max = Math.max(max, cntMap.get(edge)); } } // 砖墙行数-最大值 return n-max; } }