轻而易举笔试题 F
一、层板等分衣柜
描述:
给定一个高度为 2000mm 的柜子空间,以及 n 个层板距离柜子底部高度,满足移动层板位置
使得层板等分衣柜的空间。计算所有移动层板的顺序。
层板号自下向上依次排列,1,2…n。层板需要考虑空间位置,不能跨层板移动。
示例 1
输入 : n = 3,zs = 50,60,1000
输出 :
3 2 1
示例 2
输入 : n = 4,zs = 50,600,700,1000
输出 :
1,4,3,2
4,1,3,2
4,3,1,2
4,3,2,1
提示 1:1 <= n <= 10
提示 2:输出结果需要按小到大排序
思路
大致分为两步来解决
- 找到第一个可以动的板子,将板子放置在对应的位置,然后修改数组的值,进行递归,不停的去找下一个能动的板子,放置在他该有的位置,然后继续递归的去寻找,在此中板子应该在的位置跟板子现在所处的位置只有几种结果,要么是在当前位置的上面,要么是在当前位置的下面,板子应该在的位置想在板子的下面还想移动,就必须卡在两个板子之间才行。不存在一个板子既能向上又能向下的情况。
- 然后就是收集结果,奈何楼主算法不过关,能想到的只有多叉树来收集结果。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MovingBoard {
public static void main(String[] args) {
moving(new int[]{
50, 60, 1000});
moving(new int[]{
50, 600, 700, 1000});
}
public static void moving(int[] temps) {
//初始化一个根节点
TreeNode treeNode = new TreeNode();
treeNode.setSelfId(0);
iteration(temps, temps.length, treeNode);
ArrayList<TreeNode> treeNodes = new ArrayList<>();
getTreeLeaf(treeNode, treeNodes);
ArrayList<List<Integer>> lists = new ArrayList<>();
for (TreeNode node : treeNodes) {
List<TreeNode> elders = node.getElders();
List<Integer> integers = new ArrayList<>();
integers.add(node.getSelfId());
//由于根节点是0 所以要排除最后一个根节点才是正确的
elders.stream().forEach(item -> {
if (item.getSelfId() != 0) {
integers.add(item.getSelfId());
}
});
Collections.reverse(integers);
lists.add(integers);
}
for (List<Integer> list : lists) {
System.out.println(list);
}
}
//获取树的叶子节点
public static void getTreeLeaf(TreeNode treeNode, List<TreeNode> leafList) {
if (treeNode.isLeaf()) {
leafList.add(treeNode);
} else {