第六周(Greedy)
目录:
- 本周完成题目
- 主要过程思路
- 相关代码
- 感想与总结
一、本周完成题目
本周共完成2道题目,2道Medium。主要是针对于本周所学的贪心算法选择了一些题目进行练习。
具体完成题目及难度如下表:
# | Title | Difficulty |
---|---|---|
55 | Jump Game | Medium |
406 | Queue Reconstruction by Height | Medium |
题目内容
1、Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
题目大意:每一个数字代表它最远能到达的距离长度,从第一个数字开始,按照对应最长长度选择合适的运动路线,判断是否能到到最后一个数字。
2、Queue Reconstruction by Height
Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue.
Note:
The number of people is less than 1,100.
Example
Input:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
Output:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
题目大意:每一个数字代表它最远能到达的距离长度,从第一个数字开始,按照对应最长长度选择合适的运动路线,判断是否能到到最后一个数字。
二、主要过程思路
本周的题目使用到了贪心算法的思想,相对而言比较简单,下面是两道题目的主要思路。
1、Jump Game:
这道题主要需要保证从开始到结束不会出现达不到的断点。
具体来说,从开始位置记录长度,同时记录最远能到达的位置(reach初始化为0)。每次比较reach和i+nums[i],即新的数字能达到的最远位置,更新最远位置。当出现i>reach,出现断点的时候停止遍历,返回false,反之,当最远位置达到末尾时返回true。
2、Queue Reconstruction by Height:
这题中将所要考虑的数据分成了两类。高度和不高于前面数据的个数。所以在处理的时候最好能将数据分开处理。首先,对于数据进行排序,排序的规则是高的在前,如果等高则数字大的在后。
完成这一步后,对于排序后的数据进行再次遍历,将每个数字放到一个新的队列中。放置的方法是类似压栈的方法,将新的数字放在最前端,同时考虑不高于前面数据的个数k的限制,因为不小于当前数字的数据已经都放在目标队列中了,所以只要保证新数字插入的位置前面有k个数字即可。待将从大到小的所有数字都放入新队列时,即可完成题目要求。
三、相关代码
Jump Game
class Solution {
public:
bool canJump(vector<int>& nums) {
int reach=0;
for(int i=0;i<nums.size()&&i<=reach;i++){
reach=max(i+nums[i],reach);
if(reach>=nums.size()-1){
return true;
}
}
return false;
}
};
Queue Reconstruction by Height
class Solution {
public:
vector<pair<int, int> > reconstructQueue( vector<pair<int, int> >& people) {
sort(people.begin(), people.end(),complare);
vector<pair<int, int> > res;
for(int i=0;i<people.size();i++){
res.insert(res.begin()+people[i].second,people[i]);
}
return res;
}
//注意函数类型,开始没加static导致一直报错。
static bool complare(const pair<int, int>& a,const pair<int, int>& b)
{
return (a.first > b.first )|| (a.first == b.first && a.second < b.second);
}
};
四、感想与总结
本周随便选择了两道greedy分类下的题目。在我的理解中,所谓的greedy,是一种局部最优的思想。以第一道Jump game为例,每一次都会找到当前最远距离,根据一步一步的最远距离,推导到最后的结果。
这种思想广泛应用于编程中,有的时候可能自己都意识不到。但是具体问题具体分析,还是要注意局部最优是否能够推到全局最优。