简体   繁体   English

查找数组在小于O(n ^ 2)内重复的次数

[英]Find the number of times a number is repeated in an array in less than O(n^2)

Sample code that I have written.But this is n^2 我写的示例代码。但这是n ^ 2

int a[]={1,4,1,5,2,2,4,3,4,1};
int b[][]=new int[5][2];
int i,j,k=0,count=1;
boolean temp=false;
for(i=0;i<a.length;i++)
{
    for(j=0;j<5;j++)
    {
        if(a[i]==b[j][0])
        {   temp=true;
            b[j][1]++;
            break;
        }
    }

    if(temp==false)
    {
        b[k][0]=a[i];
        b[k][1]=1;
        k++;    
    }
    temp=false;
}
for(i=0;i<5;i++)
{
    for(j=0;j<1;j++)
    {
    System.out.println(b[i][j]+" is repeated "+b[i][j+1]+" times");
    }
}

Here's a solution in pseudocode: 这是伪代码的解决方案:

Map<Int, Int> histogram;
for(number in array) {
    histogram[number]++;
}

Now histogram[somenumber] contains the number of times the number is in the array - in O(n) assuming the Map looks up items in O(1) 现在histogram[somenumber]包含数字在数组中的次数 - 在O(n)假设MapO(1)查找项目

Option 1: sacrifice memory for speed. 选项1:牺牲记忆速度。

  • Use a data structure like a HashMap to record frequencies of each number. 使用像HashMap这样的数据结构来记录每个数字的频率。
  • Iterate through in O(n) time to build the frequency counts, then either iterate through whole HashMap or extract one value. 在O(n)时间内迭代以构建频率计数,然后迭代整个HashMap或提取一个值。

Option 2: sort 选项2:排序

  • Sort, then either iterate through the whole sorted structure or O(log n) to seek to a particular value. 排序,然后迭代整个排序结构或O(log n)以寻找特定值。
    • Quicksort has average n log n, O(n^2) worst case, is in-place for memory. Quicksort具有平均n log n,O(n ^ 2)最坏情况,就地存储器。
    • Mergesort or heapsort are O(n log n) but takes up extra memory during sort Mergesort或heapsort是O(n log n)但在排序期间占用额外的内存

Pseudocode: 伪代码:

counts = dictionary default to 0

for each element in list:
    counts[element]+=1

O(n) 上)

You should use eg. 你应该使用eg。 merge sort to sort your array and then use a simple for-loop to go through the whole array to count the repeats. 合并排序以对数组进行排序,然后使用简单的for循环遍历整个数组来计算重复次数。

Merge sort has n*log(n) and a for-loop to find the repeats is also quick. 合并排序有n * log(n),而for循环查找重复也很快。

A fast sorting algorithm should be much faster than O(n^2), and that followed by a group, which is O(n) should still be faster than O(n^2). 快速排序算法应该比O(n ^ 2)快得多,然后是一个组,即O(n)应该仍然比O(n ^ 2)快。

Therefore, in pseudocode: 因此,在伪代码中:

    group (sort [1,2,3,3,2,1])   =>   [(1,2), (2,2), (3,2)] 

You can achive in O(n) time by creating another datastructure like map. 您可以通过创建另一个数据结构(如地图)在O(n)时间内完成。 Ex: int a[]={1,4,1,5,2,2,4,3,4,1}; 例如:int a [] = {1,4,1,5,2,2,4,3,4,1};

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

for(int i = 0; i < a.length ; i++)
{
    if(map.containsKey(a[i]))
    {
        map.put(a[i], map.get(a[i])+1);
    }
    else
    {
        map.put(a[i], 1);
    }
}

System.out.print(map);

Result: {1=3, 2=2, 3=1, 4=3, 5=1} 结果:{1 = 3,2 = 2,3 = 1,4 = 3,5 = 1}

Why do you use a 2-dim array? 为什么使用2-dim阵列? If your numbers are known to be in range 1..5, use the index for the number: 如果已知您的数字在1..5范围内,请使用该数字的索引:

    int a[] = {1,4,1,5,2,2,4,3,4,1};
    int b[] = new int[5];

    for (int n : a)
        ++b[n-1];

    for (int j=0; j < 5; ++j)
        System.out.println (j + " is repeated " + b [j-1] + " times");
  • Don't declare Variables premature, and don't reuse them. 不要声明变量过早,也不要重复使用它们。 You will forget to delete unused variables (count), and get hard to analyze code. 您将忘记删除未使用的变量(计数),并难以分析代码。
  • Use the improved for : loop. 使用改进的for:loop。
  • Declare counters in the head - there is a reason why this is allowed: for (int i = ...) and why i isn't visible outside the block. 在头部声明计数器 - 这是允许的原因:for(int i = ...)以及为什么我在块外不可见。 It's not expensive. 它不贵。 No, it isn't. 不,不是。 Look at the bytecode. 看一下字节码。

If you can alter the existing array you can do this. 如果您可以更改现有阵列,则可以执行此操作。 Its O(n log(n)) and doesn't create an new objects. 它的O(n log(n))并不会创建新对象。 (If you cannot alter the original you can clone it.) Its much more efficient than maintaining a Map. (如果你无法改变原作,你可以克隆它。)它比维护Map更有效。 ;) ;)

int a[] = {1, 4, 1, 5, 2, 2, 4, 3, 4, 1};

Arrays.sort(a);
int last = a[0];
int count = -1; 
for (int i : a) {
    if (i == last) {
        count++;
        continue;
    }
    System.out.println("Number " + last + " found " + count + " times.");
    count = 1;
    last = i;
}
System.out.println("Number " + last + " found " + count + " times.");

prints 版画

Number 1 found 3 times.
Number 2 found 2 times.
Number 3 found 1 times.
Number 4 found 3 times.
Number 5 found 1 times.

Reducing O(n^2) to O(n*log n) is simple in this case: 在这种情况下,将O(n ^ 2)减少到O(n * log n)很简单:

  1. Sort the numbers using heapsort/quicksort ... O(n*log n) 使用heapsort / quicksort对数字进行排序... O(n * log n)
  2. Traverse the array once and count unique elements and get their counts ... O(n) 遍历数组一次并计算唯一元素并得到它们的计数...... O(n)

Keeping a height balanced tree with numbers as keys along with the occurrence count is another idea which will give O(n*log n). 保持一个高度平衡的树,数字作为键以及出现次数是另一个想法,它将给出O(n * log n)。 I don't see an O(n) solution without using a hash-table like data structure which is readily available in most languages. 我没有看到O(n)解决方案没有使用大多数语言中容易获得的数据结构的散列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 所有号码都被重复少于 N 次 - all number have been rebeated less than N times 给定一个+ ve整数数组,找到在O(n)时间和常数空间中出现奇数次的数字。 - Given an array of +ve integers, Find the number which occurs odd number of times in O(n) time & constant space. 如何找到一个数字在Java数组中重复多少次 - How to find how many times a number is repeated in an array in java 在小于 N 的数字中找到每个数字的总和为 d 的数字的数量 - Find the number of numbers where the sum of each number is d in numbers less than N 程序找到重复n个字符的字符串中的&#39;a&#39;数? - Program to find the number of 'a' in a string that is repeated n characters? 给定数字n,我们必须找出小于或等于n的正好有3个除数的数字 - given a number n , we have to find out such numbers that are less than or equal to n, that have exactly 3 divisors 找到小于O(N)的序列的第n项 - Find nth term of a sequence in less than O(N) 如何在O(n)中的排序数组中找到两个总和为给定数字的数字? - How to find two number whose sum is given number in sorted array in O(n)? 打印出素数小于给定数N - Print out prime Number less than a given number N 从排序数组中查找小于O(n)的唯一数字 - Finding unique numbers from sorted array in less than O(n)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM