欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【LeetCode】406. 根据身高重建队列

程序员文章站 2022-04-17 13:26:08
...

【LeetCode】406. 根据身高重建队列

我的直观思路是搜索回溯算法,加上剪枝。也就是dfs,深度优先遍历。

但是最终的结果是超出时间限制,看来需要换一种耗时少的算法。

【LeetCode】406. 根据身高重建队列

public class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 用搜索回溯的方法来解题。
        int len = people.length;// 一共有len个人
        int count = 0; // 排序到第count个人
        LinkedList<int[]> path = new LinkedList<>();// 保存路径。
        int[][] res = new int[len][2];// 存储结果
        boolean[] mark = new boolean[len];
        dfs(people, len, count, path, res, mark);
        return res;
    }

    /**
     *
     * @param people 原始的数组。
     * @param len    原始数组的长度
     * @param count  排序到第count个人
     * @param path   保存路径
     * @param res    存储结果
     * @param mark   标记是否放到path中
     */
    private void dfs(int[][] people,
                     int len,
                     int count,
                     LinkedList<int[]> path,
                     int[][] res,
                     boolean[] mark) {
        if (count == len) {// 最后一个了,可以保存结果退出了
            for (int i = 0; i < len; i++) {
                res[i][0] = path.get(i)[0];
                res[i][1] = path.get(i)[1];
            }
            return;
        }

        // 进行遍历
        for (int i = 0; i < len; i++) {
            int[] tmp = people[i]; // 获取第i个人的信息。
            if (mark[i]) {// 说明已经在path中了
                continue;
            }
            int sum = 0;
            int height = tmp[0];//这个人的身高
            for (int[] ints : path) {
                if (ints[0] >= height) {
                    sum++;
                }
            }
            if (sum != tmp[1]) {// 不满足身高计数,continue
                continue;
            }
            // 没在path中,并且满足身高计数
            mark[i] = true;
            path.add(tmp);
            count++;
            dfs(people, len, count, path, res, mark);
            count--;
            path.removeLast();
            mark[i] = false;
        }

    }
}

思路很新奇。对高个子人来说,“看不见”矮个子的人。所以先排序 高个子的人, 然后将矮个子的人插入其中。

【LeetCode】406. 根据身高重建队列

public class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 思路很新奇。对高个子人来说,“看不见”矮个子的人。
        // 所以先排序 高个子的人, 然后将矮个子的人插入其中。
        Arrays.sort(people, new Comparator<int[]>() {
            @Override
            public int compare(int[] arr1, int[] arr2) {
                if (arr1[0] == arr2[0]) {// 如果身高相同,按照第二个数值排序
                    return arr1[1] - arr2[1];
                } else {// 如果身高不同,按照身高的降序排列
                    return arr2[0] - arr1[0];
                }
            }
        });
        // 现在已经排序完成。然后进行, 插队就可以了。
        int len = people.length;
        for (int i = 0; i < len; i++) {// 遍历这个数组
            if (people[i][1] == i) {// 如果序号 一致 的话,就不用插队了
                continue;
            } else {// 说明要进行插队
                int height = people[i][0];
                int index = people[i][1];
                for (int j = i - 1; j >= index; j--) {// 这些序号的都需要 向后移动一个位置
                    people[j + 1][0] = people[j][0];
                    people[j + 1][1] = people[j][1];
                }
                people[index][0] = height;
                people[index][1] = index;
            }
        }


        return people;
    }
}

我这里写的方法中,自己实现,插队。但是其实LinkedList中 void add(int index, E element) 可以实现插队。时间又有所优化。

【LeetCode】406. 根据身高重建队列

public class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 思路很新奇。对高个子人来说,“看不见”矮个子的人。
        // 所以先排序 高个子的人, 然后将矮个子的人插入其中。
        Arrays.sort(people, new Comparator<int[]>() {
            @Override
            public int compare(int[] arr1, int[] arr2) {
                if (arr1[0] == arr2[0]) {// 如果身高相同,按照第二个数值排序
                    return arr1[1] - arr2[1];
                } else {// 如果身高不同,按照身高的降序排列
                    return arr2[0] - arr1[0];
                }
            }
        });
        // 现在已经排序完成。然后进行, 插队就可以了。
        LinkedList<int[]> list = new LinkedList<>();
        for (int[] person : people) {
            list.add(person[1], person);
        }
        return list.toArray(new int[people.length][2]);
    }
}

相关标签: 算法