Skip to content

Commit 5096147

Browse files
committed
第一周作业#25
1 parent 4f00c05 commit 5096147

File tree

3 files changed

+526
-0
lines changed

3 files changed

+526
-0
lines changed

Week_01/id_25/LeetCode_42_025.java

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package highFrequencyLeetcode.leetcode_42;
2+
3+
import java.util.Stack;
4+
5+
/**
6+
* Hard
7+
* (注解文档查看快捷键 选中类名或方法名 按ctrl + Q)
8+
* <p>
9+
* 思维全过程记录方案:<p>
10+
* 1 背基础结构和算法 | 记录在课程笔记<p>
11+
* 2 看题 -> 悟题 思考过程 | 记录在wiki<p>
12+
* 3 悟题 -> 写题 实现难点 | 记录在代码注解<p>
13+
* 4 写题 -> 优化 多种解法 | 记录在leetcode提交
14+
* <p>
15+
* 题解方案topics:
16+
* array、双指针、stack
17+
*
18+
* @author li tong
19+
* @date 2019/6/3 10:18
20+
* @see Object
21+
* @since 1.0
22+
*/
23+
public class LeetCode_42_025 {
24+
25+
public static void main(String[] args) {
26+
int[] testcase = new int[]{2, 0, 2}; // 0, 2, 0
27+
System.out.println("FORCE=" + bruteForce(testcase));
28+
System.out.println();
29+
System.out.println("DP_ONE=" + dpOne(testcase));
30+
System.out.println();
31+
System.out.println("DP_TWO=" + dpTwo(testcase));
32+
System.out.println();
33+
System.out.println("STACK=" + stack(testcase));
34+
}
35+
36+
/**
37+
* 解法1 暴力求解<p>
38+
* 看题解,提取主干思路:<p>
39+
* &nbsp;&nbsp;从左向右遍历整个下标 每个下标从左、右分别找出最高的杆子<p>
40+
* 自己学习 思考 实践时的难点(难点是如何突破的见wiki):<p>
41+
* &nbsp;&nbsp;看了题解才知道居然要从左、右分头遍历,这个一开始是想不到的
42+
*
43+
* @param columns
44+
* @return
45+
*/
46+
public static int bruteForce(int[] columns) {
47+
int result = 0, length = columns.length;
48+
for (int i = 0; i < length; i++) {
49+
// Caution 1 声明位置在for循环里面而不是外面
50+
int maxl = 0, maxr = 0;
51+
for (int j = i; j < length; j++) {
52+
maxr = Math.max(maxr, columns[j]);
53+
}
54+
for (int j = i; j >= 0; j--) {
55+
maxl = Math.max(maxl, columns[j]);
56+
}
57+
result += Math.min(maxl, maxr) - columns[i];
58+
}
59+
return result;
60+
}
61+
62+
/**
63+
* 解法2 DP求解<p>
64+
* 看题解,提取主干思路:<p>
65+
* &nbsp;&nbsp;在解法一的基础上 由于是求极值问题 考虑DP<p>
66+
* 自己学习 思考 实践时的难点(难点是如何突破的见wiki):<p>
67+
* &nbsp;&nbsp;由于在暴力求解中DP递推方程已得出,现在需要思考<p>
68+
* &nbsp;&nbsp;1 如何用dp的方式遍历 还是和暴力一样吗?<p>
69+
* &nbsp;&nbsp;2 如何归并?<p>
70+
* &nbsp;&nbsp;看完样例代码,发现遍历的顺序和暴力是有区别的,为什么?<p>
71+
*
72+
* @param columns
73+
* @return
74+
*/
75+
public static int dpOne(int[] columns) {
76+
// Caution 1 if length == 0
77+
if (columns.length == 0) {
78+
return 0;
79+
}
80+
int result = 0, length = columns.length;
81+
int[] maxl = new int[columns.length];
82+
int[] maxr = new int[columns.length];
83+
maxl[0] = columns[0];
84+
// Caution 2 length - 1
85+
maxr[length - 1] = columns[length - 1];
86+
for (int i = 1; i < length; i++) {
87+
// Caution 3 i - 1 i + 1
88+
maxl[i] = Math.max(maxl[i - 1], columns[i]);
89+
}
90+
// Caution 4 length - 2
91+
for (int i = length - 2; i >= 0; i--) {
92+
maxr[i] = Math.max(maxr[i + 1], columns[i]);
93+
}
94+
for (int i = 1; i < columns.length - 1; i++) {
95+
result += Math.min(maxl[i], maxr[i]) - columns[i];
96+
}
97+
return result;
98+
}
99+
100+
/**
101+
* 解法3 DP求解 单次遍历<p>
102+
* 看题解,提取主干思路:<p>
103+
* &nbsp;&nbsp;双指针替换两次遍历<p>
104+
* 自己学习 思考 实践时的难点(难点是如何突破的见wiki):<p>
105+
* &nbsp;&nbsp;虽然用dp存储了一些计算结果,但还是和暴力一样遍历了两次,如何减少循环次数?<p>
106+
*
107+
* @param columns
108+
* @return
109+
*/
110+
public static int dpTwo(int[] columns) {
111+
int result = 0, left = 0, right = columns.length - 1;
112+
int maxl = 0, maxr = 0;
113+
while (left < right) {
114+
if (columns[left] < columns[right]) {
115+
if (columns[left] >= maxl) {
116+
maxl = columns[left];
117+
} else {
118+
result += (maxl - columns[left]);
119+
}
120+
++left;
121+
} else {
122+
if (columns[right] >= maxr) {
123+
maxr = columns[right];
124+
} else {
125+
result += (maxr - columns[right]);
126+
}
127+
--right;
128+
}
129+
}
130+
return result;
131+
}
132+
133+
/**
134+
* 解法4 栈解法<p>
135+
* 看题解,提取主干思路:<p>
136+
* &nbsp;&nbsp;使用栈标记低谷和两界<p>
137+
* 自己学习 思考 实践时的难点(难点是如何突破的见wiki):<p>
138+
* &nbsp;&nbsp;1 很难想到<p>
139+
* &nbsp;&nbsp;2 即便看了答案也是很难理解<p>
140+
*
141+
* @param columns
142+
* @return
143+
*/
144+
public static int stack(int[] columns) {
145+
int result = 0, cursor = 0, length = columns.length;
146+
Stack<Integer> stack = new Stack<>();
147+
while (cursor < length) {
148+
// System.out.print("CURSOR" + cursor + "->");
149+
// System.out.print("COLUMN");
150+
if (stack.isEmpty() || columns[cursor] < columns[stack.peek()]) {
151+
// System.out.println(cursor + "+");
152+
stack.push(cursor++);
153+
} else {
154+
int bottom = stack.pop();
155+
// System.out.print(bottom + "- RESULT+");
156+
if (stack.isEmpty()) {
157+
// System.out.println(0);
158+
continue;
159+
}
160+
int left = stack.peek();
161+
int square = (Math.min(columns[left], columns[cursor]) - columns[bottom]) * (cursor - left - 1);
162+
// System.out.println(square);
163+
result += square;
164+
}
165+
}
166+
return result;
167+
}
168+
169+
}

0 commit comments

Comments
 (0)