最小步数归零问题
问题解析
问题描述
小R拿到了一个长度为 n 的数组,其中每个元素都是一个正整数。小R发现每次可以删除某个数组中某个数的一位数字,这样可以逐步将所有数字变为 0。他想知道,要将数组中所有数字都变为 0,最少需要多少步?
输入输出
-
输入:
n:数组的长度。a:一个包含n个正整数的数组。
-
输出:
- 一个整数,表示将数组中所有数字都变为
0所需的最少步数。
- 一个整数,表示将数组中所有数字都变为
测试样例
-
样例1:
- 输入:
n = 5, a = [10, 13, 22, 100, 30] - 输出:
7 - 解释:
10需要 1 步,13需要 2 步,22需要 2 步,100需要 1 步,30需要 1 步,总共 7 步。
- 输入:
-
样例2:
- 输入:
n = 3, a = [5, 50, 505] - 输出:
4 - 解释:
5需要 1 步,50需要 1 步,505需要 2 步,总共 4 步。
- 输入:
-
样例3:
- 输入:
n = 4, a = [1000, 1, 10, 100] - 输出:
4 - 解释:
1000需要 1 步,1需要 1 步,10需要 1 步,100需要 1 步,总共 4 步。
- 输入:
思路解析
1. 遍历数组
遍历数组中的每个数字,对于每个数字,计算将其变为 0 所需的最少步数。
2. 计算步数
对于每个数字,从最低位开始,逐位检查是否为 0。如果某位不为 0,则需要一步将其删除。将数字不断除以 10,直到数字变为 0。
3. 累加步数
将每个数字的步数累加,得到最终的总步数。
代码实现
package main
import "fmt"
func solution(n int, a []int) int {
count := 0
for i := 0; i < n; i++ {
t := a[i]
for t > 0 {
if t%10 > 0 {
count++
}
t = t / 10
}
}
return count
}
func main() {
fmt.Println(solution(5, []int{10, 13, 22, 100, 30}) == 7)
fmt.Println(solution(3, []int{5, 50, 505}) == 4)
fmt.Println(solution(4, []int{1000, 1, 10, 100}) == 4)
}
代码解析
-
初始化:
count:用于记录总步数。
-
遍历数组:
- 使用
for i := 0; i < n; i++遍历数组a。
- 使用
-
计算步数:
- 对于每个数字
t,使用for t > 0循环,逐位检查是否为0。 - 如果
t%10 > 0,则需要一步将其删除,count加1。 - 将
t除以10,继续检查下一位。
- 对于每个数字
-
返回结果:
- 返回
count,表示将数组中所有数字都变为0所需的最少步数。
- 返回
总结
通过上述方法,我们可以高效地计算出将数组中所有数字都变为 0 所需的最少步数。该方法的时间复杂度为 O(n * m),其中 n 是数组的长度,m 是数字的最大位数。这种方法在处理大规模数据时也能保持较高的效率。
珠子颜色去重
问题解析
问题描述
小S拥有一条由 n 颗珠子组成的手链,每颗珠子都有一个对应的颜色编号。她希望将手链上相同颜色的珠子进行去重,只保留每种颜色最后出现的那颗珠子,同时保持珠子原来的相对顺序。
输入输出
-
输入:
n:珠子的数量。a:一个包含n个整数的数组,表示每颗珠子的颜色编号。
-
输出:
- 一个整数数组,表示去重后的珠子颜色编号,保持原来的相对顺序。
测试样例
-
样例1:
- 输入:
n = 8, a = [1, 2, 1, 3, 4, 2, 4, 4] - 输出:
[1, 3, 2, 4] - 解释:颜色
1最后出现在索引2,颜色2最后出现在索引5,颜色3最后出现在索引3,颜色4最后出现在索引7。
- 输入:
-
样例2:
- 输入:
n = 5, a = [5, 5, 5, 5, 5] - 输出:
[5] - 解释:颜色
5最后出现在索引4。
- 输入:
-
样例3:
- 输入:
n = 6, a = [6, 1, 2, 6, 1, 2] - 输出:
[6, 1, 2] - 解释:颜色
6最后出现在索引3,颜色1最后出现在索引4,颜色2最后出现在索引5。
- 输入:
思路解析
1. 记录最后一次出现的索引
使用一个 map 记录每种颜色最后出现的索引。
2. 遍历数组
遍历数组,检查当前颜色是否是最后一次出现。如果是,则将其添加到结果数组中。
代码实现
package main
import (
"fmt"
"reflect"
)
func solution(n int, a []int) []int {
last := map[int]int{}
// 记录每种颜色最后出现的索引
for i := 0; i < n; i++ {
last[a[i]] = i
}
res := []int{}
// 遍历数组,只保留每种颜色最后出现的那颗珠子
for i := 0; i < n; i++ {
if last[a[i]] == i {
res = append(res, a[i])
}
}
return res
}
func main() {
fmt.Println(reflect.DeepEqual(solution(8, []int{1, 2, 1, 3, 4, 2, 4, 4}), []int{1, 3, 2, 4}))
fmt.Println(reflect.DeepEqual(solution(5, []int{5, 5, 5, 5, 5}), []int{5}))
fmt.Println(reflect.DeepEqual(solution(6, []int{6, 1, 2, 6, 1, 2}), []int{6, 1, 2}))
}
代码解析
-
记录最后一次出现的索引:
- 使用
map记录每种颜色最后出现的索引。 - 遍历数组
a,将每个颜色的最后出现索引记录在last中。
- 使用
-
遍历数组:
- 再次遍历数组
a,检查当前颜色是否是最后一次出现。 - 如果是,则将其添加到结果数组
res中。
- 再次遍历数组
-
返回结果:
- 返回结果数组
res,表示去重后的珠子颜色编号,保持原来的相对顺序。
- 返回结果数组
总结
通过上述方法,我们可以高效地实现去重操作,并保持珠子原来的相对顺序。该方法的时间复杂度为 O(n),其中 n 是珠子的数量。这种方法在处理大规模数据时也能保持较高的效率。