当前位置: 首页 > 知识库问答 >
问题:

在O(log n)时间内计数排序int数组中具有相同数字的数字

咸昀
2023-03-14

我遇到了一个面试问题,要求候选人计算数组中具有相同数字的所有数字。例如:

计算所有与int input=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个答案

李俭
2023-03-14

这个解决方案几乎是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;
}
束研
2023-03-14

您可以对数组进行预处理以构造Map,方法是通过映射到该规范化表示的数组中的数字的“字符串表示已排序的数字”。在该步骤之后,单个查找是O(1)O(log(n)),具体取决于所选的映射。甚至有多少数字匹配都没关系,因为您只是返回一个预构造的数组。

因此,查找确实可以非常快地进行。但前提是您要么打折预处理步骤,要么在多次查找中摊销它。

欧阳玺
2023-03-14

Andy Turner和JB Nizet给出了最好的答案,但不幸的是只是作为评论:

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

  1. 计算输入数字的所有排列。有些排列可能是相同的,如果数字有重复的数字,则只取一次。这需要O(1)时间,置换的数量也是O(1)

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

请注意,只有当输入数字的界限很低时,这才可行。如果输入的数字可以有20位数,那么最好使用O(n)方法,除非n非常大。

 类似资料:
  • 我有一张这样的桌子: 我想按组排序,然后按count(名称)排序,然后按rand()排序,结果如下: 我写了这个查询,但是如果我在group和rand之间添加count(Name),它会给我一个坏结果

  • 我被要求做一个按升序对数组进行排序的程序。我这样做了: 输入不会超过10个数字。这可以用比我这里更少的代码完成吗?我希望代码尽可能短。任何帮助都将不胜感激。谢谢!

  • 经过仔细的研究和思考,我决定发布这个问题,这是我今天早些时候提出的上一个问题的“续集”。 我做了一个算法,可以找到ArrayList的中值,基本上我所做的就是创建一个临时ArrayList,然后使用集合。在那个ArrayList上,我可以很容易地得到中值。问题是,对于较大的文件来说需要花费太长的时间,我正在尝试(运气不佳)找到一种算法的实现,以获得未排序数组(或ArrayList)的中值。 从我在

  • 例如:{1,2,3,4,-3}输出将是4,因为1+2+3+4的和是最大和,该序列中有4个数字 我知道如何用O(n^2)的时间复杂度来做这件事,但不知道如何用O(n)的帮助?:)

  • 这是一个众所周知的问题的略微修改版本,但我似乎无法理解这一点。 我们得到一个大小为n的数组,它包含无序的正数序列,没有重复项。我试图找到数组中未包含的最小正数,但我无法以任何方式对数组进行排序或编辑。整个过程应该是O(nlogn)时间和O(logn)空间的复杂性。 我能想到的所有解都是多项式时间复杂度的。

  • NowCoder 题目描述 // html Input: nums = 1, 2, 3, 3, 3, 3, 4, 6 K = 3 Output: 4 解题思路 // java public int GetNumberOfK(int[] nums, int K) { int first = binarySearch(nums, K); int last = binarySearc