我正在解决HackerRank中最长的子序列问题。我正在使用动态编程算法来解决最长的子序列问题。我的算法的时间复杂度是O(n ^ 2)。虽然我的解决方案提供了正确的结果,但它可以用于大多数测试用例。我无法改进算法,因此可以更快地计算结果。如果有人可以提出任何建议,请告诉我。我的功能如下:
static ArrayList<Integer> calcSolution(int[] arr) throws Exception{
ArrayList<ArrayList<Integer>> prev = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> lis = new ArrayList<Integer>();
lis.add(arr[0]);
prev.add(lis);
for(int i=1 ; i<arr.length ; i++){
prev.add(new ArrayList<Integer>());
for(int j=0 ; j<i ; j++){
if( (arr[i] > arr[j]) && (prev.get(i).size() < (prev.get(j).size()+1)) ){
prev.get(i).addAll(prev.get(j));
}
}
prev.get(i).add(new Integer(arr[i]));
}
for(int i=0 ; i<prev.size() ; i++){
for(int j=0 ; j<prev.get(i).size(); j++){
System.out.print(prev.get(i).get(j));
}
System.out.println();
}
lis = prev.get(0);
for(int i=1 ; i<prev.size() ; i++){
if(prev.get(i).size() > lis.size()){
lis = prev.get(i);
}
}
return lis;
}
我的问题是: - 我可以对此算法做些什么来加快速度。另一篇文章中提出的算法是完全不同的算法。
答案 0 :(得分:0)
您的实现具有时间复杂度O(n ^ 3)而不是O(n ^ 2)。
prev.get(i).addAll(prev.get(j));
是不必要且昂贵的。
对于每个元素,您需要记住上一个链接以及以此结束的子序列的长度。您不需要记住每个元素的实际子序列。