您的位置:首页 > 其它

leetcode-488-Zuma Game

2017-01-19 00:00 537 查看
摘要: 挺有意思的一个题目

祖玛游戏

原文

Think about Zuma Game. You have a row of balls on the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several balls in your hand.

Each time, you may choose a ball in your hand, and insert it into the row (including the leftmost place and rightmost place). Then, if there is a group of 3 or more balls in the same color touching, remove these balls. Keep doing this until no more balls can be removed.

Find the minimal balls you have to insert to remove all the balls on the table. If you cannot remove all the balls, output -1.

举例

Examples:

Input: "WRRBBW", "RB"
Output: -1
Explanation: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW

Input: "WWRRBBWW", "WRBRW"
Output: 2
Explanation: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> WWBB[B]WW -> WWWW -> empty

Input:"G", "GGGGG"
Output: 2
Explanation: G -> G[G] -> GG[G] -> empty

Input: "RBYYBBRRB", "YRBGB"
Output: 3
Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty

限制条件

You may assume that the initial row of balls on the table won’t have any 3 or more consecutive balls with the same color.
The number of balls on the table won't exceed 20, and the string represents these balls is called "board" in the input.
The number of balls in your hand won't exceed 5, and the string represents these balls is called "hand" in the input.
Both input strings will be non-empty and only contain characters 'R','Y','B','G','W'.

解决办法

思路

初看没有办法下手,其实是一个递归的求解过程。

这么来想,看看现在场上有几个球,然后拿手上的球去配,看看是否够满足消除条件,在消除掉几个球后,场上剩余的球及手中的球,还是一个递归的子问题。

递推公式

F(n) = F(n-1) + 消费的球个数

终止条件

场上没有球了,都消除掉了,返回成功

场上还有球,但是手里没有球了,返回失败

伪代码

find(boards, hands) {
clean(boards);
if (empty(boards)) {
return 0;
}
if (empty(hands)) {
return 0;
}
for (each in boards) {
if (不连续) {
if (hands 满足需要的数量) {
hands = hands - 数量;
boards = boards - 数量;
find(boards, hands);
}
}
}
}

Java实现

public class Solution {
public int findMinStep(String board, String hand) {
List<Character> boards = new ArrayList<>();
for (char c: board.toCharArray()) {
boards.add(c);
}
Map<Character, Integer> hands = new HashMap<>();
hands.put('R', 0);
hands.put('Y', 0);
hands.put('B', 0);
hands.put('G', 0);
hands.put('W', 0);
for (char h: hand.toCharArray()) {
hands.put(h, hands.get(h) + 1);
}
return find(boards, hands);
}

public int find(List<Character> boards, Map<Character, Integer> hands) {
clearBoard(boards);
if (boards.size() <= 0) {
return 0;
}
if (empty(hands)) {
return -1;
}
int count = 0;
int min = Integer.MAX_VALUE;
for (int i = 0; i < boards.size(); i++) {
Character c = boards.get(i);
count++;
if (i >= boards.size() - 1 || boards.get(i + 1) != c) {
int need = 3 - count;
if (hands.get(c) >= need) {
List<Character> small = new ArrayList<>(boards);
for (int j = 0; j < count; j++) {
small.remove(i - j);
}
hands.put(c, hands.get(c) - need);
int smallerFind = find(small, hands);
if (smallerFind > -1) {
min = Math.min(min, smallerFind + need);
}
hands.put(c, hands.get(c) + need);
}
count = 0;
}

}
return (min == Integer.MAX_VALUE) ? -1 : min;
}

private void clearBoard(List<Character> board) {
int count = 0;
boolean cleaned = false;
for (int i = 0; i < board.size(); i++) {
char c = board.get(i);
count++;
if (i == board.size() - 1 || board.get(i + 1) != c) {
if (count >= 3) {
for (int j = 0; j < count; j++) {
board.remove(i - j);
}
cleaned = true;
break;
}
count = 0;
}
}
if (cleaned) {
clearBoard(board);
}
}

private boolean empty(Map<Character, Integer> hand) {
for (int val: hand.values()) {
if (val > 0)
return false;
}
return true;
}
}

题目地址

https://leetcode.com/problems/zuma-game/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: