2019 力扣杯-校园自行车分配

这是我的解法,不一定好,仅供参考,欢迎大家提出更好的解法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:

1、先计算所有工人和自行车之间的距离,保存在一个二维数组里
行代表工人,列代表自行车编号
每一行就是一位工人到所有自行车的距离
2、遍历每一个工人X,找每一行的最小值,如果这个最小值对应的自行车已经被使用了,则找第二小的值,以此类推。记录这个最小值所在的索引,也就是自行车的编号。
遍历这个索引所在的列,看看有没有比它更小的值的工人Y(即工人Y离这个自行车更近)或者值一样但是工人Y的索引比当前工人X的索引小(题意要求),如果没有,则这个工人就选择这个自行车,记录下来;如果有,再判断一下这个工人Y是不是已经有分配了,如果没有分配,就直接进入下一次循环(因为也不能确定这个自行车一定被分配给工人Y);如果有分配了,则这个工人X就选择这个自行车,记录下来。
3、遍历完整个数组后,计算一下是不是每个工人都有分配了,如果没有就继续重复步骤2直到所有工人都分配了自行车。

代码:

public int[] assignBikes(int[][] workers, int[][] bikes) {
        int len1 = workers.length;
        int len2 = bikes.length;
        int[][] worker_bike = new int[len1][len2];
        int[] assign = new int[len1];
        boolean[] isUse = new boolean[len1];
        boolean[] bike_use = new boolean[len2];
        boolean flag = true;
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                worker_bike[i][j] = Math.abs(workers[i][0] - bikes[j][0]) + Math.abs(workers[i][1] - bikes[j][1]);
            }
        }
        while (flag) {
            for (int i = 0; i < len1; i++) {
                int min = 100000;
                int index = -1;
                boolean flag1 = true;
                if(isUse[i]==true)
                    continue;
                for (int j = 0; j < len2; j++) {
                    if (worker_bike[i][j] < min && !bike_use[j]) {
                        min = worker_bike[i][j];
                        index = j;
                    }
                }
                if(index==-1){
                    flag=false;
                    break;
                }
                for (int k = 0; k < len1; k++) {
                    if (((worker_bike[k][index] < min && k != i) || (worker_bike[k][index] == min && k < i)) && !isUse[k]) {
                        flag1 = false;
                        break;
                    }
                }
                if (flag1) {
                    isUse[i] = true;
                    bike_use[index] = true;
                    assign[i] = index;
                }
            }
            int count=0;
            for(int l=0;l<len1;l++){
                if(isUse[l]==true)
                    count++;
            }
            if(count==len1){
                flag=false;
                break;
            }
        }
        return assign;
    }

测试数据:

我给出一些测试数据供大家参考,我的这个代码肯定是对的,依我的经验,这些测试样例如果你都对,你的代码就是对的。
int[][] workers = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
int[][] bikes = {{0, 999}, {1, 999}, {2, 999}, {3, 999}, {4, 999}};

int[][] workers = {{0, 0}, {1, 1}, {2, 0}};
int[][] bikes = {{1, 0}, {2, 2}, {2, 1}};

int[][] workers = {{0, 0}, {2, 1}};
int[][] bikes = {{1,2}, {3,3}};

int[][] workers = {{0, 0}, {1, 1},{2,0}};
int[][] bikes = {{0,1}, {2,2},{2,1}};

int[][] workers = {{0, 0}, {1, 1},{2,0}};
int[][] bikes = {{1,0}, {2,2},{3,1}};

int[][] workers={{240,446},{745,948},{345,136},{341,68},{990,165},{165,580},{133,454},{113,527}};
int[][] bikes={{696,140},{95,393},{935,185},{767,205},{387,767},{214,960},{804,710},{956,307}};

int[][] workers={{240,446},{345,136},{341,68}};
int[][] bikes={{696,140},{95,393},{935,185},{767,205}};

int[][] workers={{460,458},{596,615},{901,893},{456,247},{690,492},{229,149},{74,792},{566,205},{660,559},{955,855}};
int[][] bikes={{272,92},{316,205},{281,371},{938,433},{218,310},{510,853},{365,626},{416,168},{365,258},{577,936}};

猜你喜欢

转载自blog.csdn.net/cjm083121/article/details/89333075