计算从头开始经历列表的次数

时间:2017-07-18 18:23:43

标签: java algorithm

我正在尝试在以下网站中解决问题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),对于非常大的数据集,它会很慢。

有没有办法以更有效的方式实现代码?

2 个答案:

答案 0 :(得分:0)

已发布社论here

  

考虑复杂度为O(n ^ 2)的解决方案。使用变量来跟踪   最后关闭的任务,从头开始完成任务列表   到最后。通过元素时增加计数器   对应下一个任务。约束非常大,所以   这个解决方案不符合时间限制。

     

我们可以的情况是什么?   在列表末尾找不到任何合适的任务?只有   一种情况:任务号(x + 1)更接近于开头   然后列出已关闭的任务编号x。因此,要解决我们的问题   可以确定任务列表中每个任务的位置并计算   不同数字x的数量使得任务编号的位置   (x + 1)小于任务编号x的位置。

     

别忘了   考虑第一次通过任务列表。最后的复杂性   解决方案是O(n)。

答案 1 :(得分:0)

  1. 遍历所有数字并将其出现的索引存储在哈希表或普通数组中,因为数字介于1-n之间。 例如,如果数字是3,4,5,2,1 这将导致像这样的哈希。 (让我们称这个指数)

    { 1 - &gt; 4, 2 - &gt; 3, 3 - &gt; 0, 4 - &gt; 1, 5 - &gt; 2 }

  2. 从1循环到n-1并找到第i个和第(i + 1)个元素的索引。

  3. loopCount = 0;

    loopCount = 0;
    for (int i=1; i<n; i++) {
        if (Index[i] > Index[i+1]) {
            loopCount++;
        }
    }
    

    时间复杂度O(n)