为高尔夫比赛砍树
你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:
0 表示障碍,无法触碰 1 表示地面,可以行走 比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度 每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。
你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。
你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1 。
可以保证的是,没有两棵树的高度是相同的,并且你至少需要砍倒一棵树。
个人题解
class Solution {
private List<Node> next = new ArrayList<>();
private Integer xMax;
private Integer yMax;
{
next.add(new Node(-1, 0, 0));
next.add(new Node(1, 0, 0));
next.add(new Node(0, -1, 0));
next.add(new Node(0, 1, 0));
}
public static void main(String[] args) {
Solution solution = new Solution();
List<List<Integer>> lists = new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>();
list.add(4);
list.add(2);
list.add(3);
lists.add(list);
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(0);
list1.add(0);
list1.add(1);
lists.add(list1);
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(7);
list2.add(6);
list2.add(5);
lists.add(list2);
int i = solution.cutOffTree(lists);
System.out.println(i);
}
public int cutOffTree(List<List<Integer>> forest) {
xMax = forest.get(0).size() - 1;
yMax = forest.size() - 1;
ArrayList<Node> nodes = new ArrayList<>();
HashMap<String, Node> passedMap = new HashMap<>();// key x,y
//按照树高度找到路径
for (int i = 0; i < forest.size(); i++) {
for (int j = 0; j < forest.get(0).size(); j++) {
Integer value = forest.get(i).get(j);
Node node = new Node(j, i, value);
if (value > 1) {
nodes.add(node);
}
String key = j + "," + i;
passedMap.put(key, node);
}
}
Collections.sort(nodes, (a, b) -> {
return a.getValue() - b.getValue();
});
Node start = new Node(0, 0, 0);
Integer result = 0;
for (Node node : nodes) { //累加每一步路径和
Integer length = bfs(start, node, passedMap);
if (length == -1) {
return length;
}
result += length;
start = node;
}
return result;
}
private Integer bfs(Node start, Node end, HashMap<String, Node> passedMap) {
if (start.equals(end)) {
return 0;
}
Integer result = 0;
Queue<Node> queue = new LinkedList<>();
queue.add(start);
String keyStart = start.getX() + "," + start.getY();
HashMap<String, Boolean> map = new HashMap<>();
map.put(keyStart, true);
while (queue.size() > 0) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Node poll = queue.poll();
//下一步能到达的坐标
for (Node nextStep : next) {
Node nextNode = new Node();
nextNode.setX(poll.getX() + nextStep.getX());
nextNode.setY(poll.getY() + nextStep.getY());
String keyNext = nextNode.getX() + "," + nextNode.getY();
if (nextNode.equals(end)) {//到达下一位置
return ++result;
}
if (!passedMap.containsKey(keyNext)
|| (map.containsKey(keyNext) && map.get(keyNext))
|| passedMap.get(keyNext).getValue() == 0) {//到达地图外或已走过位置或为非障碍路段
continue;
}
map.put(keyNext, true);
queue.add(nextNode);
}
}
result++;
}
return -1;
}
private class Node {
private Integer x;
private Integer y;
private Integer value;
private Boolean passed;
public Node() {
}
public Boolean getPassed() {
return passed;
}
public void setPassed(Boolean passed) {
this.passed = passed;
}
public Node(Integer x, Integer y, Integer value) {
this.x = x;
this.y = y;
this.value = value;
this.passed = false;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return x == node.x && y == node.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
}