860.柠檬水找零
思路:本题场景非常固定,一共就三种情况,
1、付5元,直接收下
2、付10元,找5元,收下10元,没有的话return false
3、付20元两种找零策略:找10+5,找5+5+5,没有的话return false
贪心思路在于付20元时,优先选择第一种找零策略,因为5元更万能一些
先确定一个维度,再确定另一个。
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five=0,ten=0,twenty=0;
for(int bill:bills){
if(bill==5) five++;
if(bill==10){
if(five==0) return false;
ten++;
five--;
}
if(bill==20){
if(ten>0&&five>0){
ten--;
five--;
twenty++;
}else if(five>=3){
five-=3;
twenty++;
}else{
return false;
}
}
}
//遍历完整个数组之后都没有return false的话,就return true
return true;
}
};
错因:最后没有return true。
406.根据身高重建队列
思路:本题先按身高从高到低进行排序,保证前面的一定高于后面的,如果身高相同的话,就按k从小到大排序,在这里我们自定义了一个排序函数。排序之后再遍历people数组,按k进行插值即可。
class Solution {
public:
static bool cmp(vector<int>& a,vector<int>& b){//定义成static类型是规定,排序的一种定义
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>> queue;
for(int i=0;i<people.size();i++){
int position=people[i][1];
queue.insert(queue.begin()+position,people[i]);
}
return queue;
}
};
452. 用最少数量的箭引爆气球
思路:本题的贪心思路就是让重叠的气球尽量在一起,用一个弓箭射。
局部最优就是让重叠的气球尽量在一起,用一只弓箭去射;全局最优就是用了最少的弓箭数。
class Solution {
public:
static bool cmp(vector<int>& a,vector<int>& b){
return a[0]<b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
int result=1;
sort(points.begin(),points.end(),cmp);
for(int i=1;i<points.size();i++){
if(points[i][0]>points[i-1][1]){
result++;
}else{
points[i][1]=min(points[i-1][1],points[i][1]);
}
}
return result;
}
};
错因:对二维数组的下标使用还不熟练。
463. 岛屿的周长
思路一:遍历每一个空格,遇到岛屿(为1),计算其上下左右的情况,遇到水域或者出界的情况就可以计算边了。
class Solution {
public:
int direction[4][2]={1,0,0,1,-1,0,0,-1};
int islandPerimeter(vector<vector<int>>& grid) {
int result=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==1){
for(int k=0;k<4;k++){
int x=direction[k][0]+i;
int y=direction[k][1]+j;
if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) result++;
}
}
}
}
return result;
}
};
错因:写成了y>=grid.size()。
思路二:先计算出总的岛屿数量,然后因为有一对相邻的两个陆地,边的总数就减2,那么计算出总的岛屿数量*4个边,再减去相邻岛屿数量*2个边即可。
result=sum*4-cover*2
class Solution {
public:
int islandPerimeter(vector<vector<int>>& grid) {
int sum=0;
int cover=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==1){
sum++;
//只用和之前的比较就可以了
if(i>0&&grid[i-1][j]==1) cover++;
if(j>0&&grid[i][j-1]==1) cover++;
}
}
}
return sum*4-cover*2;
}
};
1254. 统计封闭岛屿的数目
思路:遇到0(陆地)时就继续向上下左右递归,不断把0同化成1,最后返回结果。
注意封闭岛屿一定是周围被水围着,不能是边界。
class Solution {
public:
bool infect(int i,int j,int row,int col,vector<vector<int>>& grid){
if(i<0||j<0||i>=row||j>=col) return false;
if(grid[i][j]!=0) return true;
else{
grid[i][j]=1;
bool up= infect(i-1,j,row,col,grid);
bool down=infect(i+1,j,row,col,grid);
bool left=infect(i,j-1,row,col,grid);
bool right=infect(i,j+1,row,col,grid);
return up&&down&&left&&right;//只要有一个返回false,就是false
}
}
int closedIsland(vector<vector<int>>& grid) {
if(grid.size()==0||grid[0].size()==0) return 0;
int result=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==0&&infect(i,j,grid.size(),grid[0].size(),grid)){
result++;
}
}
}
return result;
}
};