• LeetCode.1051-身高检查器(Height Checker)


    这是小川的第390次更新,第420篇原创

    01 看题和准备

    今天介绍的是LeetCode算法题中Easy级别的第252题(顺位题号是1051)。要求学生按身高递增的顺序站列来拍年度照片。

    返回没有站在正确位置的学生人数。(这是必须移动的学生人数,以便所有学生身高能够以递增的顺序排列。)

    例如:

    输入:[1,1,4,2,1,3]
    输出:3
    说明:身高4,3和最后身高1的学生没有站在正确的位置。

    注意

    • 1 <= heights.length <= 100

    • 1 <= heights[i] <= 100

    02 第一种解法

    题目很简单,找出没有按高度增序站的学生人数即可。

    思路:将原数组的值复制一份出来,将其排序,使用Arrays类的sort方法完成,再与原数组对应位置的元素比较,值不相等就加1,最后返回总人数。

    时间复杂度为O(N log(N)),空间复杂度为O(N)

    public int heightChecker(int[] heights) {
        int count = 0, n = heights.length;
        int[] copy = Arrays.copyOf(heights, n);
        Arrays.sort(copy);
        for (int i=0; i<n; i++) {
            if (heights[i] != copy[i]) {
                count++;
            }
        }
        return count;
    }
    

    03 第二种解法

    还记得前几天详细介绍过的计数排序吗?此题就可以用上,此解法是简单版实现。

    时间复杂度为O(N),空间复杂度为O(N)

    public int heightChecker2(int[] heights) {
        int[] count = new int[101];
        for (int num : heights) {
            count[num]++;
        }
        int n = heights.length, index = 0;
        int[] result = new int[n];
        for (int i=0; i<count.length; i++) {
            while (count[i] > 0) {
                result[index++] = i;
                count[i]--;
            }
        }
        int times = 0;
        for (int i=0; i<n; i++) {
            if (heights[i] != result[i]) {
                times++;
            }
        }
        return times;
    }
    

    04 第三种解法

    进阶版的计数排序算法实现。

    时间复杂度为O(N),空间复杂度为O(N)

    public int heightChecker3(int[] heights) {
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int num : heights) {
            min = Math.min(min, num);
            max = Math.max(num, max);
        }
        int[] count = new int[max-min+1+1];
        for (int num : heights) {
            count[num-min+1]++;
        }
        for (int i=1; i<count.length; i++) {
            count[i] += count[i-1];
        }
        int n = heights.length;
        int[] result = new int[n]; 
        for (int j=0; j<n; j++) {
            result[count[heights[j]-min]++] = heights[j];
        }
        int times = 0;
        for (int i=0; i<n; i++) {
            if (heights[i] != result[i]) {
                times++;
            }
        }
        return times;
    }
    

    05 第四种解法

    针对简版的计数排序算法,我们还可以再简化下,在将排序后的元素填充到新数组时,顺便与原数组的对应元素进行比较,省掉后面单独再开一个for循环来比较。

    时间复杂度为O(N),空间复杂度为O(N)

    public int heightChecker4(int[] heights) {
        int[] count = new int[101];
        for (int num : heights) {
            count[num]++;
        }
        int n = heights.length, index = 0;
        int times = 0;
        int[] result = new int[n];
        for (int i=0; i<count.length; i++) {
            while (count[i] > 0) {
                result[index] = i;
                if (heights[index] != result[index]) {
                    times++;
                }
                index++;
                count[i]--;
            }
        }
        return times;
    }
    

    06 小结

    算法专题目前已连续日更超过七个月,算法题文章258+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

    以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

  • 相关阅读:
    Windows下Android开发环境搭建
    解决Win7下打开或关闭Windows功能空白一片
    C#中得到程序当前工作目录和执行目录的一些方法
    创业者必看的小故事
    Sql Server 2005外围应用应用配置器打不开了怎么办
    vs2005无法Web调试
    SQL Server 全局变量
    转 document.documentElement与document.body
    [转]使用SSMA将Oracle数据库转成SQL Server 2008
    Delphi 2009、C++Builder2009正式发布
  • 原文地址:https://www.cnblogs.com/xiaochuan94/p/11229598.html
Copyright © 2020-2023  润新知