描述
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
生成一个sqaures
记下level,其实代表是进入的层数
记下每一个remain的值,放进queue中,弹出queue的值进行,判断
如果之前出现的remain,不需要再次加入到queue中重复计算,使用marked的布尔数组
代码
public int numSquares(int n) {
List<Integer> squares = generateSquares(n);
Queue<Integer> queue = new LinkedList<>();
boolean[] marked = new boolean[n + 1];
queue.offer(n);
marked[n] = true;
int level = 0;
while (!queue.isEmpty()) {
int size = queue.size();
level++;
while (size-- > 0) {
int cur = queue.poll();
for (int square : squares) {
int remain = cur - square;
if (remain < 0) {
break;
}
if (remain == 0) {
return level;
}
if (marked[remain]) {
continue;
}
marked[remain] = true;
queue.add(remain);
}
}
}
return -1;
}
private List<Integer> generateSquares(int n) {
List<Integer> squares = new ArrayList<>();
int base = (int) Math.sqrt(n);
for (int i = 1; i <= base; i++) {
squares.add((int) Math.pow(i, 2));
}
return squares;
}
补充
队列的常用操作
q.empty() 判断队列是否为空,空返回ture,否则返回false。
q.size() 返回队列元素个数。
q.pop() 删除队首元素,但不返回值。
q.front() 返回队头元素,但不删除该元素。
q.back() 返回队尾元素,但不删除该元素。
q.push() 在队尾压入一个新元素。
q.offer() 将指定元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false,不会抛异常
3、定义优先队列
Priority_queue<类型名>变量名
4、队列的常用操作
q.empty() 判断队列是否为空,空返回ture,否则返回false。
q.size() 返回队列元素个数。
q.pop() 删除队首元素,但不返回值。
q.top() 返回具有最高优先级的元素的值,但不删除该元素。
q.push() 在基于优先级的适当位置插入新元素。
动态数组
1、定义动态数组
Vector<类型名>变量名
2、动态数组的操作
A[i] 返回动态数组中的第i个元素。
a.empty() 判断动态数组是否为空,若为空返回true,否则返回false。
a.size 返回动态数组中元素的个数。
a.resize() 修改动态数组大小。
a.push_back() 向动态数组尾部插入一个元素。
a.pop_back() 删除动态数组尾部的一个元素。
a.begin() 返回指向vector头部的迭代器(指针)。
a.end() 返回指向vector尾部元素的后一个元素的迭代器(指针)。
集合
set是STL中一种标准关联容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。set,顾名思义是“集合”的意思,在set中元素都是唯一的,而且默认情况下会对元素自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允许重复那么可以使用multiset
集合的常用运算:
sets,t,st;
setiterator it;
s.begin() 返回set容器的第一个元素
s.end() 返回set容器的最后一个元素
s.clear() 删除set容器中的所有的元素
s.empty() 判断set容器是否为空
s.max_size() 返回set容器可能包含的元素最大个数
s.size() 返回当前set容器中的元素个数
s.insert(x) 集合的插入
s.find(x) 查找元素是否存在(s.find(x)==s.end()不存在)
s.count(x) 查找元素是否存在,存在true,否则返回false。
遍历集合可以看到集合是有序的