排序题目:高度检查器

题目

标题和出处

标题:高度检查器

出处:1051. 高度检查器

难度

2 级

题目描述

要求

学校打算为全体学生拍一张年度纪念照。根据要求,学生需要按照非递减的高度顺序排成一行。排序后的高度情况用整数数组 expected \texttt{expected} expected 表示,其中 expected[i] \texttt{expected[i]} expected[i] 是排在这一行中第 i \texttt{i} i 位的学生的预期高度(下标从 0 \texttt{0} 0 开始)。

给定整数数组 heights \texttt{heights} heights,表示学生站位的当前顺序,其中 heights[i] \texttt{heights[i]} heights[i] 是这一行中第 i \texttt{i} i 位学生的高度(下标从 0 \texttt{0} 0 开始)。

返回满足 heights[i] ≠ expected[i] \texttt{heights[i]} \ne \texttt{expected[i]} heights[i]=expected[i]下标数量

示例

示例 1:

输入: heights   =   [1,1,4,2,1,3] \texttt{heights = [1,1,4,2,1,3]} heights = [1,1,4,2,1,3]
输出: 3 \texttt{3} 3
解释:
高度: [1,1,4,2,1,3] \texttt{[1,1,4,2,1,3]} [1,1,4,2,1,3]
预期: [1,1,1,2,3,4] \texttt{[1,1,1,2,3,4]} [1,1,1,2,3,4]
下标 2 \texttt{2} 2 4 \texttt{4} 4 5 \texttt{5} 5 处的学生高度不匹配。

示例 2:

输入: heights   =   [5,1,2,3,4] \texttt{heights = [5,1,2,3,4]} heights = [5,1,2,3,4]
输出: 5 \texttt{5} 5
解释:
高度: [5,1,2,3,4] \texttt{[5,1,2,3,4]} [5,1,2,3,4]
预期: [1,2,3,4,5] \texttt{[1,2,3,4,5]} [1,2,3,4,5]
所有下标的对应学生高度都不匹配。

示例 3:

输入: heights   =   [1,2,3,4,5] \texttt{heights = [1,2,3,4,5]} heights = [1,2,3,4,5]
输出: 0 \texttt{0} 0
解释:
高度: [1,2,3,4,5] \texttt{[1,2,3,4,5]} [1,2,3,4,5]
预期: [1,2,3,4,5] \texttt{[1,2,3,4,5]} [1,2,3,4,5]
所有下标的对应学生高度都匹配。

数据范围

  • 1 ≤ heights.length ≤ 100 \texttt{1} \le \texttt{heights.length} \le \texttt{100} 1heights.length100
  • 1 ≤ heights[i] ≤ 100 \texttt{1} \le \texttt{heights[i]} \le \texttt{100} 1heights[i]100

解法一

思路和算法

由于要求拍照时学生按照非递减的高度顺序排列,排序后的高度情况是整数数组 expected \textit{expected} expected,因此数组 expected \textit{expected} expected 为数组 heights \textit{heights} heights 升序排序之后的结果。

为了得到数组 expected \textit{expected} expected,需要创建与数组 heights \textit{heights} heights 相同长度的数组 expected \textit{expected} expected,将数组 heights \textit{heights} heights 中的元素复制到数组 expected \textit{expected} expected 中,然后对数组 expected \textit{expected} expected 升序排序,即可得到排序后的数组 expected \textit{expected} expected

对数组 expected \textit{expected} expected 排序之后,同时遍历数组 heights \textit{heights} heights 和数组 expected \textit{expected} expected,统计对应元素不相等的下标数量。

代码

class Solution {
    public int heightChecker(int[] heights) {
        int length = heights.length;
        int[] expected = new int[length];
        System.arraycopy(heights, 0, expected, 0, length);
        Arrays.sort(expected);
        int diff = 0;
        for (int i = 0; i < length; i++) {
            if (heights[i] != expected[i]) {
                diff++;
            }
        }
        return diff;
    }
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 heights \textit{heights} heights 的长度。需要 O ( n ) O(n) O(n) 的时间将数组 heights \textit{heights} heights 中的元素复制到数组 expected \textit{expected} expected 中,对数组 expected \textit{expected} expected 排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间,遍历两个数组统计对应元素不相等的下标数量需要 O ( n ) O(n) O(n) 的时间,总时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 heights \textit{heights} heights 的长度。需要创建长度为 n n n 的数组 expected \textit{expected} expected,对数组 expected \textit{expected} expected 排序需要 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间,空间复杂度是 O ( n ) O(n) O(n)

解法二

思路和算法

解法一需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间复杂度。如果使用计数代替排序,则可以降低时间复杂度。

首先得到学生高度的最大值,然后对每个高度计数。得到计数之后,按照升序顺序同时遍历每个高度和数组 heights \textit{heights} heights。假设数组 heights \textit{heights} heights 有序,高度 height \textit{height} height 的计数为 count \textit{count} count,则遍历数组 heights \textit{heights} heights 中的 count \textit{count} count 个元素,这些元素都等于 height \textit{height} height,如果这 count \textit{count} count 个元素中存在不等于 height \textit{height} height 的元素,则每个不等于 height \textit{height} height 的元素表示一个高度不匹配的位置。

以示例 1 为例。高度数组 heights = [ 1 , 1 , 4 , 2 , 1 , 3 ] \textit{heights} = [1, 1, 4, 2, 1, 3] heights=[1,1,4,2,1,3],计数数组 counts = [ 0 , 3 , 1 , 1 , 1 ] \textit{counts} = [0, 3, 1, 1, 1] counts=[0,3,1,1,1](计数数组的下标从 0 0 0 开始)。同时遍历计数数组 counts \textit{counts} counts 和高度数组 heights \textit{heights} heights

  1. 高度 height = 1 \textit{height} = 1 height=1 counts [ 1 ] = 3 \textit{counts}[1] = 3 counts[1]=3,遍历 heights \textit{heights} heights 3 3 3 个元素 1 , 1 , 4 1, 1, 4 1,1,4,有 1 1 1 个元素不等于 1 1 1,计数加 1 1 1

  2. 高度 height = 2 \textit{height} = 2 height=2 counts [ 2 ] = 1 \textit{counts}[2] = 1 counts[2]=1,遍历 heights \textit{heights} heights 1 1 1 个元素 2 2 2,计数不变;

  3. 高度 height = 3 \textit{height} = 3 height=3 counts [ 3 ] = 1 \textit{counts}[3] = 1 counts[3]=1,遍历 heights \textit{heights} heights 1 1 1 个元素 1 1 1,有 1 1 1 个元素不等于 3 3 3,计数加 1 1 1

  4. 高度 height = 4 \textit{height} = 4 height=4 counts [ 4 ] = 1 \textit{counts}[4] = 1 counts[4]=1,遍历 heights \textit{heights} heights 1 1 1 个元素 3 3 3,有 1 1 1 个元素不等于 4 4 4,计数加 1 1 1

遍历结束之后得到计数 3 3 3 即为答案。

代码

class Solution {
    public int heightChecker(int[] heights) {
        int maxHeight = 0;
        for (int height : heights) {
            maxHeight = Math.max(maxHeight, height);
        }
        int[] counts = new int[maxHeight + 1];
        for (int height : heights) {
            counts[height]++;
        }
        int diff = 0;
        for (int height = 1, index = 0; height <= maxHeight; height++) {
            int count = counts[height];
            for (int i = 1; i <= count; i++) {
                if (heights[index] != height) {
                    diff++;
                }
                index++;
            }
        }
        return diff;
    }
}

复杂度分析

  • 时间复杂度: O ( n + m ) O(n + m) O(n+m),其中 n n n 是数组 heights \textit{heights} heights 的长度, m m m 是数组 heights \textit{heights} heights 的最大值。需要 O ( n ) O(n) O(n) 的时间得到数组 heights \textit{heights} heights 的最大值并对每个高度计数,需要 O ( n + m ) O(n + m) O(n+m) 的时间统计高度不匹配的下标数量,总时间复杂度是 O ( n + m ) O(n + m) O(n+m)

  • 空间复杂度: O ( m ) O(m) O(m),其中 m m m 是数组 heights \textit{heights} heights 的最大值。计数需要 O ( m ) O(m) O(m) 的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值