Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目:给定一个数组people,其中表示第i个人的身高为 正好有个身高大于或等于的人,原始数组为乱序排列。要求重新构造队列。
解题思路
对于两个维度的数据,我们应该首先确定一个维度,之后在此基础上进行另一个维度的确定,在本题中,我们应该首先对身高进行从高到低的排序,如果身高相同,则按照另一个维度从大到小排序,最后遍历此数组,根据维度依次插入即可得到正确答案,注意此处为插入。
为什么身高从高到低排序而不是从低到高:因为插入过程中高的先插入对低的没有影响,但低的对高的有影响。可得代码如下:
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, (p1, p2)->{
if(p1[0]==p2[0]) return p1[1] - p2[1];
return p2[0] - p1[0];
});
ArrayList<int[]> list = new ArrayList<>();
for (int[] person : people) {
list.add(person[1], person);
}
return list.toArray(new int[0][]);
}
时间复杂度为,空间复杂度为。
LeetCode 135.分发糖果
我们可以再看一个和本题有点类似的题目:
n个孩子站成一排,给定一个ratings表示每个孩子的评分。要求按照以下标准给孩子分发糖果:
- 每个孩子至少一个糖果
- 相邻两个孩子评分更高的孩子会获得更多糖果
返回最少的糖果数目。
解题思路
本题可以从左到右得到局部最优解,再从右到左得到全局最优解,这个顺序是固定的。具体解题思路可看代码注释部分:
public int candy(int[] ratings) {
int len = ratings.length;
int[] candy = new int[len];
for(int i=0;i<len;i++){
// 每人先发一个糖
candy[i] = 1;
}
for(int i=1;i<len;i++){
// 如果后面的人分数比前面的高,比前面的多发一个糖
// 保证了从左到右满足条件
if(ratings[i]>ratings[i-1]) candy[i] = candy[i-1] + 1;
}
for(int j=len-2;j>=0;j--){
// 如果前面的人分数比后面的高,则前面的要比后面的多一个糖
// 但不能简单的等于后面的加一,因为前面的糖很可能已经大于后面的糖了(不能忽视第一次遍历的)
// 例如 [1,3,4,5,2]
// 前面的序列得到的糖果 [1, 2, 3, 4, 1]
// 从后往前序列为 [1, 2, 3, 4, 1] 此处的4就维持不变
if(ratings[j]>ratings[j+1]) candy[j] = Math.max(candy[j], candy[j+1] + 1);
}
int count = 0;
for(int i=0;i<len;i++){
count += candy[i];
}
return count;
}
时间复杂度为。