代码随想录算法训练营第35天|● 860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球 ● 463. 岛屿的周长 ● 1254. 统计封闭岛屿的数目

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;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值