有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,
其中 boxes[i] 的值为 '0' 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 '1' 表示盒子里有 一个 小球。
在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。
第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。
注意,操作执行后,某些盒子中可能会存在不止一个小球。
返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。
每个 answer[i] 都需要根据盒子的 初始状态 进行计算。
示例 1:输入:boxes = "110" 输出:[1,1,3]
解释:每个盒子对应的最小操作数如下:
1) 第 1 个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作。
2) 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2 个盒子,需要 1 步操作。
3) 第 3 个盒子:将一个小球从第 1 个盒子移动到第 3 个盒子,需要 2 步操作。将一个小球从第 2 个盒子移动到第 3 个盒子,需要 1 步操作。共计 3 步操作。
示例 2:输入:boxes = "001011" 输出:[11,8,5,4,3,4]
提示:n == boxes.length
1 <= n <= 2000
boxes[i] 为 '0' 或 '1'
解题思路分析1、遍历;时间复杂度O(n),空间复杂度O(n)
func minOperations(boxes string) []int {
n := len(boxes)
res := make([]int, n)
right, rightCount := 0, 0
for i := 0; i < n; i {
if boxes[i] == '1' {
right = right i
rightCount
}
}
left, leftCount := 0, 0
for i := 0; i < n; i {
res[i] = left right
if boxes[i] == '1' {
leftCount
rightCount--
}
left = left leftCount
right = right - rightCount
}
return res
}
2、前缀和 后缀和;时间复杂度O(n),空间复杂度O(n)
func minOperations(boxes string) []int {
n := len(boxes)
res := make([]int, n)
pre := make([]int, n)
count, sum := 0, 0
for i := 0; i < n; i {
pre[i] = sum
if boxes[i] == '1' {
count
}
sum = sum count
}
suf := make([]int, n)
count, sum = 0, 0
for i := n - 1; i >= 0; i-- {
suf[i] = sum
if boxes[i] == '1' {
count
}
sum = sum count
}
for i := 0; i < n; i {
res[i] = pre[i] suf[i]
}
return res
}
3、暴力法;时间复杂度O(n^2),空间复杂度O(n)
func minOperations(boxes string) []int {
n := len(boxes)
res := make([]int, n)
arr := make([]int, 0)
for i := 0; i < n; i {
if boxes[i] == '1' {
arr = append(arr, i)
}
}
for i := 0; i < n; i {
for j := 0; j < len(arr); j {
res[i] = res[i] abs(arr[j]-i)
}
}
return res
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
总结
Medium题目,理解题目意思比较好做,多种解法
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved