的问题,我试图解决:寻找最小的“分解”方号码
给定一个int n
,返回此int
的最小的“分解”到里面全是方形的数字。
我们在这里定义因式分解的方式不是通常的方式:k
到m
数字()的因式分解将如此:m1 + m2 + m3 + ... = k
。
例如:让n = 12
。最佳解决方案是:[4,4,4]
,因为4是2的平方和4 + 4 + 4 = 12
。也有[9,1,1,1]
,虽然它不是最小的,因为它是前者的4个数字而不是3个。
我试图解决这个问题:
我的想法是给定的,我们将执行以下算法,数字n
:
首先,我们将找到最近的平方数来n
(例如,如果n = 82
我们将找到81.
然后我们将递归计算我们得到的数减去最接近它的平方
这里是一个流程示例:假设n = 12
和我们的f我们计算f(3)
UNION {9}
然后f(12-4)
UNION {4}
然后f(12-2)
UNION {2}
。从每个我们得到一个方形组合列表,我们从这些列表中选出最小列表。我们将这些保存在HashMap中以避免重复(动态编程风格)。在Java中(不完全)
代码尝试:
public List<Integer> getShortestSquareList(int n){
HashMap<Integer,List<Integer>> map = new HashMap<Integer,List<Integer>();
map.put(1, 1);
List<Integer> squareList = getSquareList(n);
return internalGetShortestSquareList(n, map, squareList);
}
List<Integer> getSquareList(int n){
List<Integer> result=new ArrayList<Integer>();
int i = 1;
while(i*i <= n){
result.add(i*i);
i++;
}
return result;
}
public int getClosestSquare(int n,List<Integer> squareList){
// getting the closestSquareIndex
}
public List<Integer> internalGetShortestSquareList(int n, HashMap<Integer m, HashMap<Integer,List<Integer>> map, List<Integer> squareList){
if (map.contains(n)) {return map.get(n);}
int closestSqureIndex=getClosestSquare(m,squareList);
List<Integer> minSquareList;
int minSize=Integer.MAX_INT;
for(int i=closestSqureIndex; i>-1; i--) {
int square = squareList.get(closestSqureIndex);
List<Integer> tempSquares= new ArrayList<Integer>(square);
tempSquares.addAll(f(n-square, map, squareList));
if (tempSquares.size() < minSize) {
minSize = tempSize;
minSquareList = tempSquares;
}
}
map.put(n, minSquareList);
return map.get(n);
}
我的问题:
看来,我的解决办法是不是最佳的(IMO)。我认为我的解决方案的时间复杂度为O(n)*O(Sqrt(n))
,因为最大递归深度为n
,最大子女数量为Sqrt(n)
。我的解决方案可能充满了错误 - 这一点对我来说并不重要。我会很感激任何指导,以找到一个更优化的解决方案(伪代码或其他)。
从描述中不清楚你是否只是看最接近的正方形,这导致贪婪但次优算法(例如12个节目)或穷举搜索。后者是最佳的,但速度太慢,甚至在记忆时也不可行。 (提示:其复杂性的大O是一个幂函数,而不是像你写的那样是一个乘法运算。) – kfx
@kfx我不明白你的意思到底是什么,你会介意详细说明你的问题吗?我认为我的问题陈述非常明确 – Idos
它是'无界背包问题',背包大小是n,项目是{1,4,9,16 ...},详细信息请参见:https://en.wikipedia.org/ wiki/Knapsack_problem#Unbounded_knapsack_problem – Sayakiss