# 第六十四周ARTS总结
# Algorithm
811ms | 9.55% Run time
41.4MB | 42.75% Memory
public int largestRectangleArea(int[] heights) {
// 最大面积
int maxArea = 0;
// 最小值
int minValue;
for (int i = 0; i < heights.length; i++) {
minValue = heights[i];
// [i, j]区间面积最大值
for (int j = i; j < heights.length; j++) {
// 重新判断最小值
if (heights[j] < minValue) {
minValue = heights[j];
}
// [i, j]区间的面积
int area = minValue * (j - i + 1);
if (area > maxArea) {
maxArea = area;
}
}
}
return maxArea;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
13ms | 33.89% Run time
41.6MB | 99.08% Memory
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) {
return 0;
}
int maxRect = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
int[] coordinate = new int[]{i, j};
if (isPossible(matrix, coordinate, maxRect)) {
int rect = findMaxRectangle(matrix, coordinate);
if (rect > maxRect) {
maxRect = rect;
}
}
}
}
return maxRect;
}
/**
* 判断当前坐标可不可能作为顶点
*
* @param matrix
* @param coordinate
* @param maxRect 目前最大矩形
* @return
*/
private boolean isPossible(char[][] matrix, int[] coordinate, int maxRect) {
// 如果是0不可能为顶点
if (matrix[coordinate[0]][coordinate[1]] == 0) {
return false;
}
// 如果左边的点为1,则该点也不能为顶点
if (coordinate[1] - 1 >= 0 && matrix[coordinate[0]][coordinate[1] - 1] == 1) {
return false;
}
// 如果剩余部分最大面积比maxRect还小,则不能为顶点
if ((matrix.length - coordinate[0]) * (matrix[0].length - coordinate[1]) < maxRect) {
return false;
}
return true;
}
/**
* 以coordinate为左上顶点的最大矩形
*
* @param matrix
* @param coordinate 矩形左上角坐标
* @return
*/
private int findMaxRectangle(char[][] matrix, int[] coordinate) {
// 最大矩形
int maxRect = 0;
// height行内的最小宽度
int minWidth = matrix[0].length;
// 高度
int height = 1;
// 以coordinate为顶点,第height列的首个坐标为1的情况下继续
while (coordinate[0] + height <= matrix.length
&& matrix[coordinate[0] + height - 1][coordinate[1]] == '1') {
int width = 0;
for (int i = coordinate[1]; i < matrix[0].length; i++) {
// 这里多了一个 `width < minWidth` 是为了减少比较
if (width < minWidth && matrix[coordinate[0] + height - 1][i] == '1') {
width++;
} else {
break;
}
}
// 重置最小宽度
if (width < minWidth) {
minWidth = width;
}
if (minWidth * height > maxRect) {
maxRect = minWidth * height;
}
height++;
}
return maxRect;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Review
# Tip
- 合理利用
layout_marginStart
与layout_goneMarginStart
可以较好的处理ConstraintLayout
布局中组件隐藏的情况 String
方法trim
和strip
的区别:trim
自Java 1就引入了;strip
Java 11才引入trim
使用ASCII判断;strip
使用Unicode判断trim
删除ASCII小于等于U+0020的字符;strip
删除所有的空白字符
- APP启动过程:
Launcher
被调用点击事件,转到Instrumentation
类的startActivity
方法Instrumentation
通过跨进程通信告诉AMS要启动应用的需求- AMS反馈
Launcher
,让Launcher
进入Paused
状态 Launcher
进入Paused
状态,AMS转到ZygoteProcess
类,并通过socket
与Zygote
通信,告知Zygote
需要新建进程Zygote
fork进程,并调用ActivityThread
的main
方法,也就是APP的入口ActivityThread
的main
方法新建了ActivityThread
实例,并新建了Looper
实例,开始loop
循环- 同时
ActivityThread
也告知AMS,进程创建完毕,开始创建Application
,Provider
,并调用Applicaiton
的attach
,onCreate
方法 - 最后就是创建上下文,通过类加载器加载
Activity
,调用Activity
的onCreate
方法
kotlin
中可以用toInt()
方法把Float
转为Integer
BigDecimal
比较大小用compareTo
而不是equals
方法,因为equals
方法还会比较精度
# Share
暂无内容