书架排书 逆序对

PayPal的一道笔试题,一个数组每一行代表书架上书的编号,每一行数组都有一个逆序对,想从逆序对小的开始排每一行的书,输入行数N,列数k, 以及N*k的数组;输出一个数组

比如输入

输出

 

 计算数组逆序对的函数是剑指offer上的,写出来不难,关键是怎么按照逆序对的大小把对应数组的顺序变换过来

数组直接输出有一个简单方法 Arrays.deepToString(num);

import java.util.*;
class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int N = sc.nextInt();
            int k = sc.nextInt();
            int[][] nums = new int[N][k];
            int[][] copy = new int[N][k];
            for(int i = 0; i < N; i++){
                for(int j = 0; j < k; j++){
                    nums[i][j] = sc.nextInt();
                    copy[i][j] = nums[i][j];
                }
            }
           Map<Integer,Integer> map = new HashMap<>();
            for(int i = 0; i < copy.length; i++){
                map.put(i,reversePairs(copy[i]));
            }
            List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
            Collections.sort(list,(a,b)->(a.getValue()-b.getValue()));
            Iterator<Map.Entry<Integer,Integer>> it = list.iterator();
            int[][] result = new int[N][k];
            int i = 0;
            while(it.hasNext()){
                Map.Entry<Integer,Integer> en = it.next();
                for(int j = 0; j < k; j++)
                  result[i][j] = nums[en.getKey()][j];
                 i++;
            }
            System.out.println(Arrays.deepToString(result));
        }

    }
    public static int reversePairs(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        return merge(nums,0,nums.length-1);
    }
    public static int merge(int[] nums, int l, int r){
        if(l >= r)
            return 0;
        int mid = l + (r - l)/2;
        int res = merge(nums,l,mid)+merge(nums,mid+1,r);
        int i = l;
        int j = mid + 1;
        int[] temp = new int[r-l+1];
        int k = 0;
        while(i <= mid && j <= r){
            if(nums[i] <= nums[j])
                temp[k++] = nums[i++];
            else{
                temp[k++] = nums[j++];
                res += mid-i+1;
            }
        }
        while(i <= mid) 
            temp[k++] = nums[i++];
        while(j <= r)
            temp[k++] = nums[j++];
        i = l;
        for(int t: temp) nums[i++] = t;
            return res;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值