开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
虽然是快乐周五,但是明天要补班....单独部署的工程也开始了
移动所有球到每个盒子所需的最小操作数
该题出自力扣的1769题 —— 移动所有球到每个盒子所需的最小操作数【中等题】,简直就是披着中等题的简单题
审题
有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 '0' 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 '1' 表示盒子里有 一个 小球。 在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。 返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。 每个 answer[i] 都需要根据盒子的 初始状态 进行计算。
- 这道题题意并不复杂,就是给出一个字符串,字符串内部都为0和1组成的二进制字符,每次对一个小球进行移动,返回每个位置所需的移动步数,并且返回一个数组
- 为了剪枝,可以使用一个列表计算带有1的下标位置,方便在后期遍历的时候,双重for循环时,无需进行重复遍历
- 这是本次的解题思路,但是可以有更高效的方式
- 记录当前盒子左侧的个数,以及右侧的个数,每次下标转移的时候,左侧的个数全数加1,右侧的减一,通过三个变量即可得出当前下标的移动步数
编码
class Solution {
public int[] minOperations(String boxes) {
List<Integer> list = new ArrayList<>();
char[] chars = boxes.toCharArray();
int len = chars.length;
for (int i = 0; i < len; i++) {
if (chars[i] == '1')list.add(i);
}
int[] a = new int[len];
for (int i = 0; i < len; i++) {
int num = 0;
for (int j = 0; j < list.size(); j++) {
if (i == list.get(j))continue;
num+=Math.abs(list.get(j) - i);
}
a[i] = num;
}
return a;
}
}