华为技术一面 09.16 光产品线 1h
- 自我介绍
- 做了一道题
import java.util.Scanner;
/**
* @author Lei
* @create 2022-09-16 14:08
*/
public class Main {
// 小孙经过多年的奋斗,终于在家乡买一下了一大块地皮。然而糟心的是黑心的开发商在某些地皮上造成了极大的破坏,以至于不能在上面盖一砖一瓦。而作为强迫症患者的小孙,希望有一块正方形的地皮来造房子,请你帮助这个可怜人找到最大的正方形地皮。
// 输入
// 第一行为两个整数n,m表示这个土地的长宽。
// 接下来n行,每行m个整数,用空格隔开,0表示该块土地被破坏,1表示该块土地完好。
// 数据范围:1 <= n, m <= 1000
// 输出
// 一个整数,最大正方形的边长。
// 样例
// 输入样例
// 4 4
// 0 1 1 1
// 1 1 1 0
// 0 1 1 0
// 1 1 0 1
// 输出样例
// 2
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int[][] map = new int[m][n];
boolean flag = false;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = scanner.nextInt();
if (map[i][j] == 1) {
flag = true;
}
}
}
if (!flag) {
System.out.println(0);
} else {
//这个是当前的一个前缀的二维矩阵
int[][] S = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + map[i - 1][j - 1];
}
}
int index = 1;
int max = -1;
while (index <= Math.min(m, n)) {
for (int j = index; j <= m; j++) {
for (int i = index; i <= n; i++) {
//哭死,就是这个没有用到,然后导致这个没有计算出来
int area = S[i][j] - S[i][j - index] - S[i - index][j] + S[i - index][j - index];
if (area == index * index) {
max = Math.max(max, index);
}
}
}
index++;
}
System.out.println(max);
}
}
}
优化:
import java.util.Scanner;
/**
* @author Lei
* @create 2022-09-16 14:08
*/
public class Main {
// 小孙经过多年的奋斗,终于在家乡买一下了一大块地皮。然而糟心的是黑心的开发商在某些地皮上造成了极大的破坏,以至于不能在上面盖一砖一瓦。而作为强迫症患者的小孙,希望有一块正方形的地皮来造房子,请你帮助这个可怜人找到最大的正方形地皮。
// 输入
// 第一行为两个整数n,m表示这个土地的长宽。
// 接下来n行,每行m个整数,用空格隔开,0表示该块土地被破坏,1表示该块土地完好。
// 数据范围:1 <= n, m <= 1000
// 输出
// 一个整数,最大正方形的边长。
// 样例
// 输入样例 1 复制
// 4 4
// 0 1 1 1
// 1 1 1 0
// 0 1 1 0
// 1 1 0 1
// 输出样例 1
// 2
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int[][] map = new int[m][n];
boolean flag = false;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = scanner.nextInt();
if (map[i][j] == 1) {
flag = true;
}
}
}
if (!flag) {
System.out.println(0);
} else {
//这个是当前的一个前缀的二维矩阵
int[][] S = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + map[i - 1][j - 1];
}
}
//从最大开始进行查找,查询速度提高
int index = Math.min(m, n);
int max = -1;
boolean flagBreak = false;
while (index >= 1) {
ok:
for (int j = index; j <= m; j++) {
for (int i = index; i <= n; i++) {
int area = S[i][j] - S[i][j - index] - S[i - index][j] + S[i - index][j - index];
if (area == index * index) {
max = Math.max(max, index);
flagBreak = true;
break ok;
}
}
}
if (flagBreak) {
break;
}
index--;
}
System.out.println(max);
}
}
} 再次总结,二维前缀和数组:
//获得前缀数组
int[][] S = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + map[i - 1][j - 1];
}
}
//得到固定长度的正方形的长度的面积
for (int j = index; j <= m; j++) {
for (int i = index; i <= n; i++) {
int area = S[i][j] - S[i][j - index] - S[i - index][j] + S[i - index][j - index];
if (area == index * index) {
max = Math.max(max, index);
}
}
}
//获取到任意的上下标的面积
//原数组的取值范围 row1 [0,m) col1 [0,n)
//原数组的取值范围 row2 [0,m) col2 [0,n)
//就是使用这个方法来计算这个这个矩阵和的时候呢,需要注意的就是他们的取值范围
public int sumRegion(int row1, int col1, int row2, int col2) {
//当前的计算方式很难的去理解,就是为啥需要这样来进行计算
return sum[row2 + 1][col2 + 1] - sum[row2 + 1][col1] - sum[row1][col2 + 1] + sum[row1][col1];
}
* 1:row1 [0,m) col1 [0,n);row2 [0,m) col2 [0,n) * 2:row1和col1是左上下标,row2和col2是右下下标 * 3:右下坐标可以和左上下标可以重合,那么当前的值就是当前左上下标的值 * 4:右下坐标和左上下标如果不重合的话,进行框中的一个面积,这个面积是包含左上和
- 将一下自己最深刻的项目经历,自己做了那个部分
- 线程和进程的区别,以及线程的创建方式
- 内存泄露知道么
- 怎么规避内存泄漏
- 没有时间了,只是问了这么多,真的要好好复盘了
10.09:等了好久的主管面,终于也是进入了池子里