【问题标题】:Sorting an array based on the number of occurrences [duplicate]根据出现次数对数组进行排序[重复]
【发布时间】:2015-04-03 06:12:53
【问题描述】:

您好,我正在尝试根据数组中值的出现次数对数组进行排序。因此,如果我的数组 int[] a = new int[]{9,2,4,8,9,4,3,2,8,1,2,7,2,5};my 数组计数应该是:count[i-1] 并且基于数组的值,我的计数数组如下所示:1 4 1 2 1 0 1 2 2 所以count[0] = 1 存储 1 的计数。count[1] =4并存储2的计数,count[2] = 1存储3的计数,count[8] =2存储9的出现次数。我的计数应该是count[i-1]来存储出现次数并基于次数我应该对数组进行排序。第一个问题,我无法将数组 a 的出现次数存储到 count 数组中。并根据出现次数如何存储数组。

【问题讨论】:

  • 如果 a[i] 的上界比较小,那么我建议计数排序
  • 目前我只看到需求。你在实现它时遇到了什么麻烦?
  • @ZiadHalabi 是的。这可能是解决方案。但我觉得这很复杂。简单地计算排序就可以了。只是一个想法
  • @sathiyaseelan OP 遇到问题将数组 a 的出现次数存储到 count 数组中,我不确定他/她是否可以实现计数排序。
  • 请提供您当前的代码并解释您的将数组 a 的出现次数存储到 count 数组中的问题。这样,我们就可以为您的问题提供准确的帮助。

标签: java arrays


【解决方案1】:

第一步是遍历数组,存储每个数字出现的次数。假设数组只能包含从1k的元素,那么我们需要一个可以存储k元素的count数组:

int k = 9;
int[] count = new int[k];

注意这个数组会在每个位置用默认值0初始化,这需要O(k)做时间和空间,所以相当于:

int[] count = {0, 0, 0, 0, 0, 0, 0, 0, 0};

所以所有元素的初始计数都是0

现在我们计算数组中的元素。

例如:

int[] a = new int[]{9,2,4,8,9,4,3,2,8,1,2,7,2,5};
// Go through each element of this array:
int n = a.length
for (int i = 0; i < n; i++) {
    // Add 1 to the corresponding position in the count array.
    int position = a[i] - 1;
    count[position]++;
}

这需要O(n) 时间,并将导致:

count = {1, 4, 1, 2, 1, 0, 1, 2, 2}

完成此操作后,数组实际上已排序。我们可以通过这样做看到这是真的:

int[] sorted = new int[n];
int h = 0;
for (int i = 0; i < count.length; i++) {
    for (int j = 0; j < count[i]; j++) {
        // Sum 1 to i to get the original number
        sorted[h++] = i + 1;
    }
}

System.out.println(Arrays.toString(sorted));

这也需要O(n)时间和空间,并输出:

[1, 2, 2, 2, 2, 3, 4, 4, 5, 7, 8, 8, 9, 9]

所以这个算法的总时间和空间复杂度是O(n + k),这意味着它在项目数加上最大和最小键值之间的差值上呈线性运行。

【讨论】:

  • 这个排序算法可以优化吗?
  • 我不这么认为,因为它已经是O(n + k)。我更新了答案以表明这一点。
  • 我理解得很清楚。非常感谢。