Skip to content

Commit 7a54af3

Browse files
committedNov 26, 2018
feat(solution): add solution 0312 [Java]
Burst Balloons
1 parent 983ad50 commit 7a54af3

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Complete [solutions](https://github.com/doocs/leetcode/tree/master/solution) to
114114
| 0084 | [Largest Rectangle in Histogram](https://github.com/doocs/leetcode/tree/master/solution/0084.Largest%20Rectangle%20in%20Histogram) | `Array`, `Stack` |
115115
| 0145 | [Binary Tree Postorder Traversal](https://github.com/doocs/leetcode/tree/master/solution/0145.Binary%20Tree%20Postorder%20Traversal) | `Stack`, `Tree` |
116116
| 0295 | [Find Median from Data Stream](https://github.com/doocs/leetcode/tree/master/solution/0295.Find%20Median%20from%20Data%20Stream) | `Heap`, `Design` |
117+
| 0312 | [Burst Balloons](https://github.com/doocs/leetcode/tree/master/solution/0312.Burst%20Balloons) | `Divide and Conquer`, `Dynamic Programming` |
117118

118119

119120
## Contributions
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## 戳气球
2+
### 题目描述
3+
4+
`n` 个气球,编号为 `0``n-1`,每个气球上都标有一个数字,这些数字存在数组 `nums` 中。
5+
6+
现在要求你戳破所有的气球。每当你戳破一个气球 `i` 时,你可以获得 `nums[left] * nums[i] * nums[right]` 个硬币。 这里的 `left``right` 代表和 `i` 相邻的两个气球的序号。注意当你戳破了气球 `i` 后,气球 `left` 和气球 `right` 就变成了相邻的气球。
7+
8+
求所能获得硬币的最大数量。
9+
10+
**说明:**
11+
12+
- 你可以假设 `nums[-1] = nums[n] = 1`,但注意它们不是真实存在的所以并不能被戳破。
13+
- 0 ≤ `n` ≤ 500, 0 ≤ `nums[i]` ≤ 100
14+
15+
**示例:**
16+
```
17+
输入: [3,1,5,8]
18+
输出: 167
19+
解释: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
20+
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
21+
22+
```
23+
24+
### 解法
25+
数组 `f` 表示某范围内(开区间)戳破所有气球能获得的最大硬币。那么题意转换为求`f[0][n+1]`
26+
27+
假设最后一个戳破的气球为 `i`,那么:
28+
```
29+
f[0][n+1] = f[0][i] + f[i][n+1] + nums[i] * nums[0][n+1]。
30+
```
31+
32+
利用记忆化搜索,遍历当最后一个戳破的气球为 `i` 时,求 `f[0][n+1]` 的最大值。
33+
34+
```java
35+
class Solution {
36+
37+
public int maxCoins(int[] nums) {
38+
if (nums == null || nums.length == 0) {
39+
return 0;
40+
}
41+
int n = nums.length;
42+
int[][] f = new int[n + 2][n + 2];
43+
for (int i= 0; i < n + 2; ++i) {
44+
for (int j = 0; j < n + 2; ++j) {
45+
f[i][j] = -1;
46+
}
47+
}
48+
int[] bak = new int[n + 2];
49+
bak[0] = bak[n + 1] = 1;
50+
for (int i = 1; i < n + 1; ++i) {
51+
bak[i] = nums[i - 1];
52+
}
53+
return dp(bak, f, 0, n + 1);
54+
}
55+
56+
private int dp(int[] nums, int[][] f, int x, int y) {
57+
if (f[x][y] != -1) {
58+
return f[x][y];
59+
}
60+
61+
f[x][y] = 0;
62+
63+
//枚举最后一个戳破的气球的位置
64+
for (int i = x + 1; i < y; ++i) {
65+
f[x][y] = Math.max(f[x][y], nums[i] * nums[x] * nums[y] + dp(nums,f, x, i) + dp(nums, f, i, y));
66+
}
67+
return f[x][y];
68+
69+
}
70+
71+
72+
}
73+
```
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
3+
public int maxCoins(int[] nums) {
4+
if (nums == null || nums.length == 0) {
5+
return 0;
6+
}
7+
int n = nums.length;
8+
int[][] f = new int[n + 2][n + 2];
9+
for (int i= 0; i < n + 2; ++i) {
10+
for (int j = 0; j < n + 2; ++j) {
11+
f[i][j] = -1;
12+
}
13+
}
14+
int[] bak = new int[n + 2];
15+
bak[0] = bak[n + 1] = 1;
16+
for (int i = 1; i < n + 1; ++i) {
17+
bak[i] = nums[i - 1];
18+
}
19+
return dp(bak, f, 0, n + 1);
20+
}
21+
22+
private int dp(int[] nums, int[][] f, int x, int y) {
23+
if (f[x][y] != -1) {
24+
return f[x][y];
25+
}
26+
27+
f[x][y] = 0;
28+
29+
//枚举最后一个戳破的气球的位置
30+
for (int i = x + 1; i < y; ++i) {
31+
f[x][y] = Math.max(f[x][y], nums[i] * nums[x] * nums[y] + dp(nums,f, x, i) + dp(nums, f, i, y));
32+
}
33+
return f[x][y];
34+
35+
}
36+
37+
38+
}

0 commit comments

Comments
 (0)
Please sign in to comment.