贪心算法|406.根据身高重建队列

力扣题目链接

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        if (a[0] == b[0]) return a[1] < b[1];
        return a[0] > b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort (people.begin(), people.end(), cmp);
        vector<vector<int>> que;
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1];
            que.insert(que.begin() + position, people[i]);
        }
        return que;
    }
};

思路理解了,但是就是看不懂代码啊

出现两个维度一起考虑的情况,我就是想不通了啊!

代码随想录 (programmercarl.com)

思路

本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。

其实如果大家认真做了135. 分发糖果 (opens new window),就会发现和此题有点点的像。

135. 分发糖果 (opens new window)我就强调过一次,遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。

如果两个维度一起考虑一定会顾此失彼

对于本题相信大家困惑的点是先确定k还是先确定h呢,也就是究竟先按h排序呢,还是先按照k排序呢?

如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。

那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。

此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!

那么只需要按照k为下标重新插入队列就可以了,为什么呢?

以图中{5,2} 为例:

按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。

所以在按照身高从大到小排序后:

局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性

全局最优:最后都做完插入操作,整个队列满足题目队列属性

局部最优可推出全局最优,找不出反例,那就试试贪心。

一些同学可能也会疑惑,你怎么知道局部最优就可以推出全局最优呢? 有数学证明么?

在贪心系列开篇词关于贪心算法,你该了解这些! (opens new window)中,我已经讲过了这个问题了。

刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心,至于严格的数学证明,就不在讨论范围内了。

如果没有读过关于贪心算法,你该了解这些! (opens new window)的同学建议读一下,相信对贪心就有初步的了解了。

回归本题,整个插入过程如下:

排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]

插入的过程:

  • 插入[7,0]:[[7,0]]
  • 插入[7,1]:[[7,0],[7,1]]
  • 插入[6,1]:[[7,0],[6,1],[7,1]]
  • 插入[5,0]:[[5,0],[7,0],[6,1],[7,1]]
  • 插入[5,2]:[[5,0],[7,0],[5,2],[6,1],[7,1]]
  • 插入[4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

此时就按照题目的要求完成了重新排列。

相关推荐
怎么没有名字注册了啊12 分钟前
查找成绩(数组实现)
c++·算法
沐怡旸22 分钟前
【算法】725.分割链表--通俗讲解
算法·面试
L_09072 小时前
【Algorithm】Day-4
c++·算法·leetcode
代码充电宝2 小时前
LeetCode 算法题【简单】20. 有效的括号
java·算法·leetcode·面试·职场和发展
海琴烟Sunshine2 小时前
leetcode 119. 杨辉三角 II python
算法·leetcode·职场和发展
小杨的全栈之路2 小时前
霍夫曼编码:数据压缩的核心算法详解(附图解 + 代码)
算法
cjinhuo2 小时前
标签页、书签太多找不到?AI 分组 + 拼音模糊搜索,开源插件秒解切换难题!
前端·算法·开源
贝塔实验室2 小时前
频偏估计方法--快速傅里叶变换(FFT)估计法
网络协议·算法·数学建模·动态规划·信息与通信·信号处理·傅立叶分析
闭着眼睛学算法3 小时前
【双机位A卷】华为OD笔试之【模拟】双机位A-新学校选址【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·javascript·c++·python·算法·华为od
玉夏3 小时前
【每日算法C#】爬楼梯问题 LeetCode
算法·leetcode·c#