在O(log n)时间中对排序的int数组中的相同数字进行计数

时间:2018-11-27 21:07:10

标签: java arrays algorithm time-complexity big-o

我遇到了一个面试问题,要求应聘者对数组中所有具有相同数字的数字进行计数。 例如:

计算与int输入= 394共享相同数字的所有数字 int [] arr = {1,14,101,349,439,745,934}

该函数将返回3,因为439、934、349共享相同的数字。 问题是如何在O(log n)时间内解决这个问题?我对Big O概念仍然陌生,除了O(n)和O(n ^ 2)...我在理解如何归档O(log n)时遇到困难。

我的第一个想法如下: 我将计算数组中所有元素的数字总和。如果总和相等,则它们包含的数字与输入数字相同。

      int counter = 0;

      while (num > 0) {
         int digitSum += num % 10;
         num = num / 10;
      }
      for(int i = 0; i < arr.length; i++) {
      int k = arr[i];

      while (k > 0) {
          int sumOfDigits += k % 10;
          k = k/10;
      }
      if(sumOfDigits == digitSum) {
       counter++;
      }
}

我知道这至少需要O(n)时间,但是我很难找到更好的解决方案。

3 个答案:

答案 0 :(得分:0)

您可以对数组进行预处理,以通过映射到该规范化表示形式的数组中数字的“字符串代表排序数字”来构建Map。完成该步骤后,根据选择的地图,分别进行jq: error: Project/0 is not defined at <top-level>, line 1: map(if .ParameterKey == Project jq: 1 compile error O(1)的查找。匹配多少个数字都没有关系,因为您只是返回一个预先构造的数组。

因此查找确实可以非常快速地进行。但是,只有在您取消预处理步骤或通过多次查找将其摊销的情况下。

答案 1 :(得分:0)

该解决方案几乎为O(n),因为与给定数组大小(n)相比,输入中的位数非常小。

想法是从每个元素中获取尽可能少的数字,并与输入数字的相应值进行比较

public static void main(String []args){

    int input = 394;
    int[] arr = {1, 14, 101, 349, 439, 745, 934};


    int ans = 0;
    int hold = getMin(input);
    for(int i = 0; i < arr.length; i++)
    {
        if(hold == getMin( arr[i] ))
        {
            ans++;
        }
    }
    System.out.println(ans);
}

public static int getMin(int n)
{
    int hold[] = new int[10];
    while( n > 0)
    {
        hold[n % 10]++;
        n /= 10;
    }

    int ans = 0;
    for(int i = 0; i < hold.length; i++)
    {
        while(hold[i] > 0)
        {
            ans = ans * 10 + i;
            hold[i]--;
        }
    }
    return ans;
}

答案 2 :(得分:0)

最好的答案是安迪·特纳(Andy Turner)和JB尼泽特(JB Nizet),但不幸的是,这只是一个评论:

为此,我们必须假设:输入数字的大小是有界的,数组中的整数是不相交的,而n是数组中元素的数量。

  1. 计算输入数字位数的所有排列。如果数字有重复的数字,则某些排列可能是相同的,请只取一次。这需要O(1)时间,排列的数量也是O(1)。
  2. 对于每个排列,使用二进制搜索在数组中查找对应的数字并计算所有匹配。这需要O(log n)。

总的运行时间为O(log n)。

请注意,这仅在输入数字的界限很低的情况下才可行。如果输入数字可以说20位数,则最好使用O(n)方法,除非n确实很大。