leetcode解题系列(六)

leetcode解题系列(六)

找到一点感觉了,每天坚持好三道题的量,多想想思路,自己动手再写一下代码,坚持就是胜利。

5750 人口最多的年份

题目描述:
给你一个二维整数数组 logs ,其中每个 logs[i] = [birthi, deathi] 表示第 i 个人的出生和死亡年份。

年份 x 的 人口 定义为这一年期间活着的人的数目。第 i 个人被计入年份 x 的人口需要满足:x 在闭区间 [birthi, deathi - 1] 内。注意,人不应当计入他们死亡当年的人口中。

返回 人口最多 且 最早 的年份。

解法:比较容易想到的就是朴素暴力解法,可以做一个一维数组,依次存放第i个人活着的年份,然后用count()函数求出每一年份出现的次数,然后求最大值就可以得到

只要能读懂题意,编写程序是不难的:
代码如下:

class Solution {
public:
    int maximumPopulation(vector<vector<int>>& logs) {
    int res=0;
    vector<int> liveyear;
    for(int i=0;i<logs.size();i++){//遍历搜索每个人
        for(int n=logs[i][0];n<logs[i][1];n++){
            liveyear.push_back(n);
        }
    }
    int min_year=*min_element(liveyear.begin(),liveyear.end());
    int max_year=*max_element(liveyear.begin(),liveyear.end());
    res=max_year;
    int po=count(liveyear.begin(),liveyear.end(),max_year-1);
    for(int m=max_year;m>min_year-1;m--){
        if(count(liveyear.begin(),liveyear.end(),m)>=po){
            res=m;
            po=count(liveyear.begin(),liveyear.end(),m);
        }
    }
    return res;      
    }
};

但我这个做法毕竟是最简单的,官方给出了一种差分数组的方法,时间和空间上都更有优势:

class Solution {
private:
    static constexpr int offset = 1950;   // 起始年份与起始下标之差
    
public:
    int maximumPopulation(vector<vector<int>>& logs) {
        vector<int> delta(101, 0);   // 变化量
        for (auto&& log: logs) {
            ++delta[log[0]-offset];
            --delta[log[1]-offset];
        }
        int mx = 0;   // 人口数量最大值
        int res = 0;   // 最大值对应的最小下标
        int curr = 0;   // 每一年的人口数量
        // 前缀和
        for (int i = 0; i < 101; ++i){
            curr += delta[i];
            if (curr > mx){
                mx = curr;
                res = i;
            }
        }
        return res + offset;   // 转回对应的年份
    }
};

delta数组是用来记录每一年的人口变化增量的,先遍历logs数组,将人口变化记录下来,然后再遍历delta数组,计算人口最多的年份。

1046、最后一块石头的重量

题目描述:
题目描述
听上去也是一道比较有意思的。
想到的方法就是先对石头进行排序,然后编程实现粉碎后,若有新石头产生就加入原来的有序数组,接下来继续这个操作,即可实现。
代码如下:

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
      sort(stones.begin(),stones.end());
      int stone1=0;
      int stone2=0;
      int stones_differ=0;
      while(stones.size()>=2){   
        stone1=stones.back();
        stones.pop_back();
        stone2=stones.back();
        stones.pop_back();  
     if(stone1!=stone2){
        stones_differ=stone1-stone2;
        stones.insert(stones.begin(),stones_differ);
        sort(stones.begin(),stones.end());  
      }
    }
    if(stones.size()==1){
        return stones[0];
    }
    return 0;
    }
};

代码的能力还要加强,一定不要老是依赖查资料,一些常识要熟练应用,还有不要老是出错,一些拼写方面还有括号,分号都要弄好,很浪费时间。

这是比较直接的算法,看看还有什么方法:
堆和优先队列,这块知识是我没有学过的,有时间看一下。

703、数据流中的第K大元素

题目描述:
在这里插入图片描述
用 最简单的方法写了一遍,但是发现时间要求不够。。
代码如下:

class KthLargest {
public:
    int k1;
    vector<int> st;
    KthLargest(int k, vector<int>& nums) {
    k1=k;
    st=nums;
    sort(st.begin(),st.end(),greater<int>());//降序排序
    }
    
    int add(int val) {
    st.insert(st.begin(),val);
    sort(st.begin(),st.end(),greater<int>());
    return st[k1-1];
    }
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

因为当每一次add都要用到sort时就会比较慢,想到一个方法,当add的数字小于现在的第K大元素,我们就把它放在末尾不用排序了,因为这个元素并不会影响后面的输出,试一下这个方法。
还是超过了时间限制

官方有C++的版本:

class KthLargest {
public:
    priority_queue<int, vector<int>, greater<int>> q;
    int k;
    KthLargest(int k, vector<int>& nums) {
        this->k = k;
        for (auto& x: nums) {
            add(x);
        }
    }
    
    int add(int val) {
        q.push(val);
        if (q.size() > k) {
            q.pop();
        }
        return q.top();
    }
};

运行速度比我的方法好太多了,但是要先学一下优先队列的相关方法;下次再学

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值