我正在尝试在以下网站中解决问题A(称为任务管理):http://codeforces.com/gym/101439/attachments/download/5742/2017-yandexalgorithm-qualification-round-en.pdf
基本上,我们给出了一个从1到n的整数的未排序列表,我们希望按顺序访问整数(即1,2,3,4,5,...... n)。我们必须多少次才能到列表的开头,直到我们按顺序访问从1到n的所有整数。
让' S说,我们有像的列表:3 2 1.通过我们访问仅编号1的列表中的第一运行期间,通过所述列表中的第二运行期间,我们访问,并且在仅数2第三轮我们终于访问了3号。所以我们必须经过3次列表。
这是我的代码:
import java.util.Scanner;
import java.util.ArrayList;
class TaskManagement{
// arr: array of tasks
static int countNumberOfLoops(ArrayList<Integer> arr){
int targetTask = 1;
// Last task to close
int finalTask = arr.size();
int index=0;
int count =0;
while(targetTask != finalTask+1){
if(index%arr.size()==0) count++;
if(arr.get(index%arr.size())==targetTask) targetTask++;
index++;
}
System.out.println(count);
return count;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
// make a static array of size n
ArrayList<Integer> arr = new ArrayList<Integer>();
for (int i=0; i<n; i++) {
int item = scan.nextInt();
arr.add(item);
}
countNumberOfLoops(arr);
}
}
问题是:我的代码效率不高, O(n ^ 2),对于非常大的数据集,它会很慢。
有没有办法以更有效的方式实现代码?
答案 0 :(得分:0)
已发布社论here:
考虑复杂度为O(n ^ 2)的解决方案。使用变量来跟踪 最后关闭的任务,从头开始完成任务列表 到最后。通过元素时增加计数器 对应下一个任务。约束非常大,所以 这个解决方案不符合时间限制。
我们可以的情况是什么? 在列表末尾找不到任何合适的任务?只有 一种情况:任务号(x + 1)更接近于开头 然后列出已关闭的任务编号x。因此,要解决我们的问题 可以确定任务列表中每个任务的位置并计算 不同数字x的数量使得任务编号的位置 (x + 1)小于任务编号x的位置。
别忘了 考虑第一次通过任务列表。最后的复杂性 解决方案是O(n)。
答案 1 :(得分:0)
遍历所有数字并将其出现的索引存储在哈希表或普通数组中,因为数字介于1-n之间。 例如,如果数字是3,4,5,2,1 这将导致像这样的哈希。 (让我们称这个指数)
{ 1 - &gt; 4, 2 - &gt; 3, 3 - &gt; 0, 4 - &gt; 1, 5 - &gt; 2 }
从1循环到n-1并找到第i个和第(i + 1)个元素的索引。
loopCount = 0;
loopCount = 0;
for (int i=1; i<n; i++) {
if (Index[i] > Index[i+1]) {
loopCount++;
}
}
时间复杂度O(n)