Skip to content

Commit c95d5e2

Browse files
authored
Improved task 488.
1 parent f2fc2ce commit c95d5e2

File tree

2 files changed

+59
-144
lines changed

2 files changed

+59
-144
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3294,7 +3294,7 @@ implementation 'com.github.javadev:leetcode-in-java:1.11'
32943294
| 0493 |[Reverse Pairs](src.save/main/java/g0401_0500/s0493_reverse_pairs/Solution.java)| Hard | Array, Binary_Search, Ordered_Set, Divide_and_Conquer, Segment_Tree, Binary_Indexed_Tree, Merge_Sort | 121 | 31.13
32953295
| 0492 |[Construct the Rectangle](src.save/main/java/g0401_0500/s0492_construct_the_rectangle/Solution.java)| Easy | Math | 1 | 74.25
32963296
| 0491 |[Increasing Subsequences](src.save/main/java/g0401_0500/s0491_increasing_subsequences/Solution.java)| Medium | Array, Hash_Table, Bit_Manipulation, Backtracking | 22 | 46.38
3297-
| 0488 |[Zuma Game](src.save/main/java/g0401_0500/s0488_zuma_game/Solution.java)| Hard | String, Dynamic_Programming, Breadth_First_Search, Memoization | 2077 | 7.41
3297+
| 0488 |[Zuma Game](src.save/main/java/g0401_0500/s0488_zuma_game/Solution.java)| Hard | String, Dynamic_Programming, Breadth_First_Search, Memoization | 1989 | 32.79
32983298
| 0486 |[Predict the Winner](src.save/main/java/g0401_0500/s0486_predict_the_winner/Solution.java)| Medium | Array, Dynamic_Programming, Math, Recursion, Game_Theory | 0 | 100.00
32993299
| 0485 |[Max Consecutive Ones](src.save/main/java/g0401_0500/s0485_max_consecutive_ones/Solution.java)| Easy | Array | 1 | 100.00
33003300
| 0483 |[Smallest Good Base](src.save/main/java/g0401_0500/s0483_smallest_good_base/Solution.java)| Hard | Math, Binary_Search | 3 | 87.88
Lines changed: 58 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,79 @@
11
package g0401_0500.s0488_zuma_game;
22

33
// #Hard #String #Dynamic_Programming #Breadth_First_Search #Memoization
4-
// #2022_04_15_Time_2077_ms_(7.41%)_Space_42.5_MB_(77.78%)
4+
// #2022_07_13_Time_1989_ms_(32.79%)_Space_56.5_MB_(81.97%)
55

6-
import java.util.ArrayList;
7-
import java.util.HashSet;
8-
import java.util.List;
9-
import java.util.Set;
6+
import java.util.HashMap;
7+
import java.util.Stack;
108

11-
@SuppressWarnings("java:S135")
129
public class Solution {
13-
public int findMinStep(String board, String hand) {
14-
List<Character> boardList = new ArrayList<>();
15-
for (char c : board.toCharArray()) {
16-
boardList.add(c);
17-
}
18-
List<Character> handList = new ArrayList<>();
19-
for (char c : hand.toCharArray()) {
20-
handList.add(c);
21-
}
22-
return findMinStep(boardList, handList);
23-
}
10+
private HashMap<String, Integer> map = new HashMap<>();
2411

25-
private int findMinStep(List<Character> boardList, List<Character> handList) {
26-
if (boardList.isEmpty()) {
27-
return 0;
28-
}
29-
if (handList.isEmpty()) {
30-
return -1;
31-
}
32-
if (!isValid(boardList, handList)) {
33-
return -1;
34-
}
35-
int res = Integer.MAX_VALUE;
36-
for (int boardListIndex = 0; boardListIndex <= boardList.size(); boardListIndex++) {
37-
Set<Character> duplicate = new HashSet<>();
38-
for (int handListIndex = 0; handListIndex < handList.size(); handListIndex++) {
39-
if (boardListIndex > 0
40-
&& boardList.get(boardListIndex - 1).equals(handList.get(handListIndex))) {
41-
continue;
42-
}
43-
if (duplicate.contains(handList.get(handListIndex))) {
44-
continue;
12+
private String removeConsecutiveThreeOrMoreBalls(String board) {
13+
Stack<Character> st = new Stack<>();
14+
int n = board.length();
15+
for (int i = 0; i < n; i++) {
16+
char ch = board.charAt(i);
17+
st.push(ch);
18+
if (st.size() >= 3 && (i == n - 1 || ch != board.charAt(i + 1))) {
19+
char a = st.pop();
20+
char b = st.pop();
21+
char c = st.pop();
22+
if (a == b && b == c) {
23+
while (!st.isEmpty() && st.peek() == a) {
24+
st.pop();
25+
}
4526
} else {
46-
duplicate.add(handList.get(handListIndex));
47-
}
48-
boolean goodCase1 =
49-
(boardListIndex < boardList.size()
50-
&& boardList
51-
.get(boardListIndex)
52-
.equals(handList.get(handListIndex)));
53-
boolean goodCase2 =
54-
(boardListIndex > 0
55-
&& boardListIndex < boardList.size()
56-
&& boardList
57-
.get(boardListIndex - 1)
58-
.equals(boardList.get(boardListIndex))
59-
&& !boardList
60-
.get(boardListIndex - 1)
61-
.equals(handList.get(handListIndex)));
62-
if (!goodCase1 && !goodCase2) {
63-
continue;
64-
}
65-
List<Character> boardListClone = new ArrayList<>(boardList);
66-
List<Character> handListClone = new ArrayList<>(handList);
67-
boardListClone.add(boardListIndex, handListClone.remove(handListIndex));
68-
cleanup(boardListClone);
69-
int preRes = findMinStep(boardListClone, handListClone);
70-
if (preRes != -1 && preRes < res) {
71-
res = preRes;
27+
st.push(c);
28+
st.push(b);
29+
st.push(a);
7230
}
7331
}
7432
}
75-
76-
if (res == Integer.MAX_VALUE) {
77-
return -1;
33+
StringBuilder res = new StringBuilder();
34+
while (!st.isEmpty()) {
35+
res.append(st.pop());
7836
}
79-
return res + 1;
37+
return res.reverse().toString();
8038
}
8139

82-
public void cleanup(List<Character> boardList) {
83-
boolean isCleanup = false;
84-
while (!isCleanup) {
85-
isCleanup = true;
86-
for (int i = 0; i < boardList.size() - 2; i++) {
87-
int repeatLen = 1;
88-
for (int j = i + 1; j < boardList.size(); j++) {
89-
if (boardList.get(j).equals(boardList.get(j - 1))) {
90-
repeatLen++;
91-
} else {
92-
break;
93-
}
94-
}
95-
if (repeatLen >= 3) {
96-
isCleanup = false;
97-
for (; repeatLen > 0; repeatLen--) {
98-
boardList.remove(i);
99-
}
100-
}
101-
}
102-
}
40+
private String ss(String s, int i, int j) {
41+
return s.substring(i, j);
10342
}
10443

105-
public boolean isValid(List<Character> boardList, List<Character> handList) {
106-
int boardR = 0;
107-
int boardY = 0;
108-
int boardB = 0;
109-
int boardG = 0;
110-
int boardW = 0;
111-
int handR = 0;
112-
int handY = 0;
113-
int handB = 0;
114-
int handG = 0;
115-
int handW = 0;
116-
for (char c : boardList) {
117-
if (c == 'R') {
118-
boardR++;
119-
}
120-
if (c == 'Y') {
121-
boardY++;
122-
}
123-
if (c == 'B') {
124-
boardB++;
125-
}
126-
if (c == 'G') {
127-
boardG++;
128-
}
129-
if (c == 'W') {
130-
boardW++;
131-
}
132-
}
133-
for (char c : handList) {
134-
if (c == 'R') {
135-
handR++;
136-
}
137-
if (c == 'Y') {
138-
handY++;
139-
}
140-
if (c == 'B') {
141-
handB++;
142-
}
143-
if (c == 'G') {
144-
handG++;
145-
}
146-
if (c == 'W') {
147-
handW++;
148-
}
149-
}
150-
if (boardR < 3 && boardR > 0 && boardR + handR < 3) {
151-
return false;
44+
private int solve(String board, String hand) {
45+
String key = board + "#" + hand;
46+
if (map.containsKey(key)) {
47+
return map.get(key);
15248
}
153-
if (boardY < 3 && boardY > 0 && boardY + handY < 3) {
154-
return false;
49+
board = removeConsecutiveThreeOrMoreBalls(board);
50+
int ans = 100, n = board.length(), m = hand.length();
51+
if (n == 0 || m == 0) {
52+
map.put(key, n == 0 ? 0 : 100);
53+
return n == 0 ? 0 : 100;
15554
}
156-
if (boardB < 3 && boardB > 0 && boardB + handB < 3) {
157-
return false;
158-
}
159-
if (boardG < 3 && boardG > 0 && boardG + handG < 3) {
160-
return false;
55+
for (int i = 0; i < hand.length(); i++) {
56+
for (int j = 0; j < n; j++) {
57+
if (board.charAt(j) == hand.charAt(i)
58+
|| (j < n - 1 && board.charAt(j) == board.charAt(j + 1))) {
59+
ans =
60+
Math.min(
61+
ans,
62+
1
63+
+ solve(
64+
ss(board, 0, j + 1)
65+
+ hand.charAt(i)
66+
+ ss(board, j + 1, n),
67+
ss(hand, 0, i) + ss(hand, i + 1, m)));
68+
}
69+
}
16170
}
162-
return boardW >= 3 || boardW <= 0 || boardW + handW >= 3;
71+
map.put(key, ans);
72+
return ans;
73+
}
74+
75+
public int findMinStep(String board, String hand) {
76+
int ans = solve(board, hand);
77+
return ans >= 100 ? -1 : ans;
16378
}
16479
}

0 commit comments

Comments
 (0)