【问题标题】:Getting rank of element upon sorting the array在对数组进行排序时获取元素的排名
【发布时间】:2017-03-23 09:10:49
【问题描述】:

给定一个数组,我想找出这些元素在排序后的数组中的位置。因此,输入和输出如下所示

Input : {10, 5, 4, 9, 8, 3, 2, 1,  6, 7}
Output: {0, 3, 4, 9, 8, 1, 2, 5, 6, 7}

这意味着,10 将位于已排序数组中的第 0 位,而 5 将位于第四个索引中,即 sortedinput[3]。

这是一个可以做到的单线

Arrays.sort(index, (a, b) -> (nums[b] - nums[a]));

方法如下所示

public Integer[] findIndexInSortedArray(int[] nums) {
        Integer[] index = new Integer[nums.length];

        for (int i = 0; i < nums.length; i++) {
            index[i] = i;
        }

        Arrays.sort(index, (a, b) -> (nums[b] - nums[a]));

        return index;
}

有没有办法在不使用 lambda 和 Java 8 的任何特性的情况下执行与上述相同的操作?是否可以仅使用 Comparator 来实现这一点?

【问题讨论】:

  • 100th 怎么样?不应该是9th
  • @buraquete 这取决于订单是降序还是升序。 OP 代码中的当前 lambda 表达式采用降序排列。
  • @Eran 那么31st 怎么样?他的最终数组是{10, 3, 2, 5, 4, 1, 6, 7, 8, 9}
  • @buraquete 你从哪里得到{10, 3, 2, 5, 4, 1, 6, 7, 8, 9}?他的最后一个数组是{0, 3, 4, 9, 8, 1, 2, 5, 6, 7}。 0是原始数组中10的索引,3是9的索引,4是8的索引,依此类推。
  • 如果nums[b] 非常大并且nums[a] 是负数,则此代码Arrays.sort(index, (a, b) -&gt; (nums[b] - nums[a])); 可能会失败。整数溢出会抬起丑陋的脑袋。见blog.mischel.com/2016/11/21/…

标签: java algorithm sorting lambda java-8


【解决方案1】:

lambda 表达式总是可以被它实现的功能接口替换(在你的例子中是Comparator&lt;Integer&gt;)。只是需要更长的时间来写:

Arrays.sort(index, new Comparator<Integer> () {
                       public int compare (Integer a, Integer b) {
                           return Integer.compare(nums[b],nums[a]);
                       }
            });

【讨论】:

  • 我不明白为什么这会被否决。这是@saltmangotree 要求的,不是吗?
  • 我会使用Integer.compare(Java 8 之前的版本)考虑到带有简单减法的溢出问题。
  • @Eran,我了解解决方案,但有一个后续问题。 Comparator 何时知道何时停止排序过程。是不是对于给定的数组,即索引,它确保对于传入的任何两个 Integer a 和 b, nums[b] 总是大于 nums[a] ?为 a 和 b 处理的元素的顺序是什么,它是否检查 a 和 b 的所有可能部分?还是这是由 Arrays.sort 内部使用的排序算法决定的?
  • @saltmangotree 比较器一无所知。做出这些决定的是排序算法。任何体面的排序算法都不会检查所有可能的对。
  • @Eran,我们可以改写如下: Comparator 不知道选择了哪两个元素,这由排序算法决定。然而,比较器所知道的是,给定两个元素,什么应该在什么之前。我这样说对吗?
【解决方案2】:

Comparator&lt;T&gt; 接口是一个FunctionalInterface,并使用注释@FunctionalInterface 标记为一个。

从 Java 8 开始,您可以将 FunctionalInterfaces 与 Lambda 表达式一起使用,就像在 Arrays.sort 方法中所做的那样。

表达式可以用anonymous inner class 替换,代码会爆炸,但结果是一样的:

public Integer[] findIndexInSortedArray(int[] nums)
{
    Integer[] index = new Integer[nums.length];

    for (int i = 0; i < nums.length; i++)
    {
        index[i] = i;
    }

    Arrays.sort(index, new Comparator<Integer>()
        {
            @Override
            public int compare(Integer a, Integer b)
            {
                return nums[b] - nums[a];
            }
        });

    return index;
}

【讨论】:

  • 您使用 Comparator 并覆盖 compare 方法的解决方案对我来说很清楚。但是我有几个关于内部工作的问题,如果你能回答的话。 Comparator 何时知道何时停止排序过程。是不是对于给定的数组,即索引,它确保对于传入的任何两个 Integer a 和 b, nums[b] 总是大于 nums[a] ?为 a 和 b 处理的元素的顺序是什么,它是否检查 a 和 b 的所有可能部分?还是这是由 Arrays.sort 内部使用的排序算法决定的?
【解决方案3】:

基本思路:

  1. 编写您自己的排序算法
  2. 在排序算法开始时,创建一个与要排序的数组大小相同的数组,填充0,1,2,3,...
  3. 调整您的排序算法,以便每次对要排序的数组执行操作时,对新数组执行相同的操作
  4. 返回新数组而不是要排序的数组

详细说明第 3 步:例如,如果您使用冒泡排序,则每次在要排序的数组中交换元素 i 和 j 时,都会交换具有相同索引的新数组中的元素

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 2020-01-07
    • 2021-02-16
    • 2019-09-02
    • 2015-06-28
    • 2016-04-11
    相关资源
    最近更新 更多