lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 题目

读题

HJ41 称砝码 

 

考查点

 

2. 解法

思路

  •  1. 暴力破解,3重循环
  • 2. 利用set 去重

可参照 

【Java 数据结构及算法实战】系列 045:HJ41 称砝码-华为开发者论坛 | 华为开发者联盟 (huawei.com)

代码逻辑

 

具体实现

public class HJ041 {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] w = new int[n];
for (int i = 0; i < n; i++) {
w[i] = sc.nextInt();
}
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
}
System.out.println(getWays(w, nums, n));
}

public static int getWays(int[] w, int[] nums, int n) {
Set<Integer> set = new HashSet<>();
set.add(0);

for (int i = 0; i < n; i++) {
List<Integer> list = new ArrayList<>(set);
for (int j = 0; j <= nums[i]; j++) {
for (int k = 0; k < list.size(); k++) {
set.add(list.get(k) + j * w[i]);
}
}
}
return set.size();
}
}

 

3. 总结

 

3.1  java 中 set 在add 时如果重了会怎么办

java 中的 set 集合在 add 时如果有重复的元素,会自动忽略掉,不会添加到集合中。这是 set 集合的特点,它只能存储不重复的元素。

如果你想要存储重复的元素,你可以考虑使用其他的集合类型,比如 list 或者 multiset。这些集合类型可以允许有重复的元素存在。

3.2 set.add 会报错吗

set.add 一般不会报错,除非你添加了不支持的元素,比如 null 或者类型不匹配的元素。但是 set.add 有可能返回 false,表示添加失败,这是因为 set 集合不能有重复的元素,如果你添加了一个已经存在的元素,它会被忽略掉。

 

3.3 set 几个实现类

  • HashSet:使用哈希表来存储元素,性能最好,但是不保证元素的顺序。
  • TreeSet:使用红黑树来存储元素,按照元素的值来排序,性能较差,但是可以使用 SortedSet 接口的操作。
  • LinkedHashSet:使用哈希表和链表来存储元素,按照元素的插入顺序来排序,性能略低于 HashSet,但是可以保证元素的顺序。
  • EnumSet:使用位向量来存储枚举类型的元素,性能非常高,但是只能用于枚举类型。

除了这些通用的 set 实现类,还有一些特殊用途的 set 实现类,比如 CopyOnWriteArraySet, ConcurrentSkipListSet, ImmutableSet 等。你可以根据你的需求和场景来选择合适的 set 实现类。

3.4  如何选择合适的 set 实现类?

如何选择合适的 set 实现类,主要取决于你对 set 的需求和场景。一般来说,你可以根据以下几个方面来考虑:

  • 元素的顺序:如果你不关心元素的顺序,你可以使用 HashSet,它是性能最好的 set 实现类,但是不保证元素的顺序。如果你需要按照元素的值来排序,你可以使用 TreeSet,它可以使用 SortedSet 接口的操作,但是性能较差。如果你需要按照元素的插入顺序来排序,你可以使用 LinkedHashSet,它可以保证元素的顺序,性能略低于 HashSet。
  • 元素的类型:如果你的元素是枚举类型,你可以使用 EnumSet,它是一个专门为枚举类型设计的高性能 set 实现类,它使用位向量来存储元素,非常节省空间。
  • 集合的大小:如果你的集合很大或者不确定大小,你需要考虑 set 实现类的容量和负载因子。容量是指 set 内部存储结构的大小,负载因子是指容量和元素数量之间的比例。一般来说,容量越大,空间消耗越高,但是避免了频繁地扩容和复制数据结构;负载因子越高,空间利用率越高,但是增加了哈希冲突和查找时间。HashSet 和 LinkedHashSet 都有容量和负载因子这两个参数,你可以根据你的需求来调整它们。TreeSet 和 EnumSet 没有这两个参数。
  • 并发访问:如果你需要在多线程环境下访问 set 集合,你需要考虑并发安全问题。一般来说,普通的 set 实现类都不是线程安全的,如果你需要线程安全的 set 实现类,你可以使用 CopyOnWriteArraySet 或者 ConcurrentSkipListSet。CopyOnWriteArraySet 是一个基于数组的线程安全的 set 实现类,它在每次修改操作时都会复制一个新的数组,适合读多写少的场景。ConcurrentSkipListSet 是一个基于跳表的线程安全的 set 实现类,它支持并发访问和排序操作,适合读写均衡的场景。
posted on 2023-07-21 14:59  白露~  阅读(49)  评论(0编辑  收藏  举报