0. 题目描述
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, …) which sum to n.
给定一个正整数
n,找出最少
个完全平方数,它们的和为n,返回个数
[点击此处跳转题目原地址](https://leetcode.com/problems/perfect-squares/description/
示例:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
1.解题思路
将题目转化成图的广度优先遍历
,每次减去一个完全平方数到下一步,查找到达零点的最短路径。通俗来讲,就是每次走一步,看怎样走先到达0点;代码示例:
int numSquares(int n) {
vector<bool> visited(unsigned (n+1), false);
queue<pair<int, int>> queue1; //构建一个队列进行搜索
queue1.push(make_pair(n, 0)); //pair的first是节点, second是步数
while(not queue1.empty()){
int node = queue1.front().first;
int step = queue1.front().second;
queue1.pop();
for (int i = 1; i * i <= node; i ++){
int nextNode = node - i * i;
if (nextNode == 0) //找到率先到达0点的,返回当前步数
return step + 1;
if (not visited[nextNode]){
queue1.push(make_pair(nextNode, step + 1));
visited[nextNode] = true;
}
}
}
return 0;
}
2. 扩展
如果想得到由这样最少个完全平方数构成的数组,该怎么办?一个很简单的想法就是,将上述代码中pair
中firs
t由存储当前节点改为存储所经过的所有节点构成的数组即可:
vector<int> numSquaresRes(int n) {
vector<int> resRoute;
bool end = false;
vector<bool> visited(unsigned (n+1), false);
queue<pair<vector<int>, int>> queue1;
queue1.push(make_pair(vector<int>(1,n), 0));
while(not queue1.empty()){
vector<int> route = queue1.front().first;
int node = route.back();
int step = queue1.front().second;
queue1.pop();
for (int i = 1; i * i <= node; i ++){
int nextNode = node - i * i;
if (nextNode == 0) { //由于队列前端存储的路径肯定比之后的路径要短或者至少相当,所以第一次到达0点,这一定是最短路径
resRoute = route;
resRoute.push_back(nextNode);
end = true;
}//找到率先到达0点的
if (not visited[nextNode]){
vector<int> nextRoute = route;
nextRoute.push_back(nextNode); //将上一次的路径加上当前节点构成当前路径
queue1.push(make_pair(nextRoute, step + 1)); //路径连同步数压入队列
visited[nextNode] = true;
}
}
if(end)
break;
}
vector<int> res;
res.reserve(resRoute.size()-1);
for (int i = 0; i < resRoute.size()-1; i++){
res.push_back(resRoute[i] - resRoute[i+1]);
}
return res;
}