java.lang.illegalargumentexception:比较方法违反了其一般约定java.base/java.util.timsort.mergecollapse

mfuanj7w  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(421)
class Solution {
    public int[] frequencySort(int[] nums) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i : nums) {
            list.add(i);
        }
        list = fun(list);
        for(int i=0;i<nums.length;i++){
            nums[i] = list.get(i);
        }
        return nums;
    }

    public ArrayList<Integer> fun(ArrayList<Integer> list){
        Map<Integer,Integer> map = new HashMap<>();

        list.forEach(i -> {
            map.put(i,map.getOrDefault(i,0)+1);
        });

        Collections.sort(list,(n1,n2) -> {
            int freq1 = map.get(n1);
            int freq2 = map.get(n2);

            if(freq1!=freq2){
                return freq1-freq2;
                // if(freq1>freq2){
                //     return 1;
                // }
                // return -1;
            }
            return n2-n1;
            //if(n1>=n2){
            //   return -1;
            //}
           // return 1;

        } );
        return list;
    }
}

//sample input : nums = [2,3,1,3,2]
//output : [1,3,3,2,2]

在collections.sort()的fun方法中,我根据频率的递增顺序对数组进行排序,如果两者的频率相同,那么我将按值的递增顺序添加它们。我从谷歌得到的上述代码运行良好,但我自己编写了几乎类似的代码,并将其作为注解包含在内。这两个代码看起来很相似,但我的代码(作为注解)只通过了85/150个测试用例,之后我得到了“java.lang.illegalargumentexception:comparison方法违反了它的一般约定!”
我发现了类似的问题,但我不能理解,有人用更简单的术语解释它!!!

//This block I found in google

if(freq1!=freq2){
    return freq1-freq2;
 }
 return n2-n1;
//Below Block gives "Comparison method violates its general contract"

if(freq1!=freq2){
       if(freq1>freq2){
          return 1;
        }
       return -1;
}
if(n1>=n2){
       return -1;
}
return 1;
628mspwn

628mspwn1#

您给出的最后一个区块作为违反合同的示例是错误的,原因如下。
例如,如果我们有两个元素 a = (5, 1)b = (5, 1) ,其中,我将每个元素表示为 (freq, n) ,然后进行比较 ab 返回 -1 指定 a 我必须早于 b 在已排序的列表中。但是,如果我们以相反的顺序比较这两个值-- ba ,给定的示例仍将返回 -1 这一次说, b 我必须早于 a .
我认为明确地考虑返回 0 如果两者都是 freqn 如果相等,则应修复最后一段代码。

相关问题