代碼隨想錄算法訓練營|第三十七天|860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球。刷题心得(c++)

本文分享了作者在解决三个编程题目(柠檬水找零、根据身高重建队列和用最少箭引爆气球)过程中的思路变化,强调了C++语言基础和容器操作的重要性。作者发现语言功底和对工具的理解对算法效率有直接影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

讀題

860.柠檬水找零

自己看到题目的第一想法

看完代码随想录之后的想法

406.根据身高重建队列

自己看到题目的第一想法

看完代码随想录之后的想法

452.用最少数量的箭引爆气球

自己看到题目的第一想法

看完代码随想录之后的想法

860.柠檬水找零 - 實作

思路

Code

406.根据身高重建队列 - 實作

思路

Code

vector

List

452.用最少数量的箭引爆气球 - 實作

思路

Code

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料


讀題

860.柠檬水找零

自己看到题目的第一想法

用三個變數去紀錄5 10 15

遍歷數列,假設為5 直接加加

如果遇到10 - 5 ,10 ++

如果是20 - 10 - 5 or 20 - 5 - 5 - 5 如果不滿足則直接return false ,

看完代码随想录之后的想法

基本上就是跟我寫的代碼差不多,只不過細部分析我沒有將先10 再5這個策略作為局部最優來想,看完之後對於這題的局部最優策略就比較清晰了。

在bill = 10 時,局部最優沒有選擇就是5,但在bill = 20 時就有兩個策略,一個是先選擇10再選擇5,另一個是選擇三個5,在局部情況上優先選擇第一個策略,在選擇第二個策略就是這題的貪心策略。

406.根据身高重建队列

自己看到题目的第一想法

看完之後,雖然知道跟分配糖果很類似,知道大概是要將身高以及前面排幾個人進行分開處理,但實際要怎麼做真的沒有想法。

看完代码随想录之后的想法

兩個維度的確立,先確認身高由大到小排序,如果身高一樣則用前面有多少人高或等於自己的維度來排序,有想過要分開這樣處理,但沒有從這個角度去思考過,身高由高到低可以基本確立前面的人一定比後面的大,之後利用第二個維度進行插入操作,因為關注的是前面比較高,所以就算後面的數字一直插入到前面,都可以保證說後面的數字仍然比前面大,使條件可以達成。

不過這題使用vector容器的話,時間上會因為vector插入的操作而導致時間拉長。

看著代碼隨想錄的總結,裡面有一段話我覺得對我來說很重要,不只學好算法,更要去了解我所使用的工具,有效率的利用。

编程语言中一个普通容器的insert,delete的使用,都可能对写出来的算法的有很大影响! 如果抛开语言谈算法,除非从来不用代码写算法纯分析,否则的话,语言功底不到位O(n)的算法可以写出O(n^2)的性能。 相信在这里学习算法的录友们,都是想在软件行业长远发展的,都是要从事编程的工作,那么一定要深耕好一门编程语言,这个非常重要!

452.用最少数量的箭引爆气球

自己看到题目的第一想法

看完之後有理解題意,但要怎麼去實作,以這題而言我還是想先看思路與解法,後續題目嘗試使用。

看完代码随想录之后的想法

自己其實對於射氣球這件事情,沒有到非常了解,但跟著李解下來,其實代碼真的沒有很難,但我對c++的語法真的沒有到非常理解

其實整體思路就三個部分

  1. 利用左邊界進行排序
  2. 遍例數組,假設左邊界與下一個的右邊界不重合則result++,否則更新右邊界,取右邊界最小的進行更新。
  3. return result.

860.柠檬水找零 - 實作

思路

  1. 用兩個個變數去紀錄5 與 10
  2. 遍歷數列
    1. 5 變數5加加
    2. 10 ,變數5不為零,則減減 ,並且10 ++
      1. 如果不滿足直接return false
    3. 20
      1. 優先策略 10減減 5 減減
      2. 次優策略 5 -= 3;
      3. 如果不滿足則直接return false ,
  3. return true;

Code

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int dollor_5 = 0;
        int dollor_10 = 0;
        for(int i = 0; i < bills.size(); i++) {
            if(bills[i] == 5) dollor_5++;
            if(bills[i] == 10) {
                if(dollor_5 > 0) dollor_5--;
                else return false;
                dollor_10++;
            }
            if(bills[i] == 20) {
                if(dollor_10 > 0 && dollor_5 > 0) {
                    dollor_10--;
                    dollor_5--;
                } else if(dollor_5 >= 3) dollor_5 -= 3;
                else return false;
            }
        }
        return true;
    }
};

406.根据身高重建队列 - 實作

思路

  1. 先確認身高由高到低進行排序
  2. 身高一樣則用k進行低到高的排序
  3. 建立一個q數組
  4. 根據k,將原數組根據k的規格進行插入操作
  5. return q數組。

Code

vector

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        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>> q;
        for(int i = 0; i < people.size(); i++) {
            int position = people[i][1];
            q.insert(q.begin() + position, people[i]);
        }
        return q;
    }
};

List

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        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);
        list<vector<int>> q;
        for(int i = 0; i < people.size(); i++) {
            int position = people[i][1];
            std::list<vector<int>>::iterator it = q.begin();
            while (position--) {
                it++;
            }
            q.insert(it, people[i]);
        }
        return vector<vector<int>>(q.begin(), q.end());
    }
};

452.用最少数量的箭引爆气球 - 實作

思路

  1. 利用左邊界進行排序
  2. 遍例數組,假設左邊界與下一個的右邊界不重合則result++,否則更新右邊界,取右邊界最小的進行更新。
  3. return result.

Code

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[0] < b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        if (points.size() == 0) return 0;
        sort(points.begin(), points.end(), cmp);
        int result = 1; 
        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;
    }
};

總結

自己实现过程中遇到哪些困难

今天在實現這三題,一樣是題二題三出了問題,但我發覺今天最大的問題不是思路,而是我對於C++操作的不熟悉,雖然在進行刷題之前有預料到,但是一些C++語言的容器操作我仍然不熟悉,另外對於思路的部分整體不難,但真的都很巧妙,需要多練習。

今日收获,记录一下自己的学习时长

今天大概學2.5hr左右,整體而言就是慢慢摸索不同的解題切入點,讓自己的腦袋多一點範例可以進行多面向的聯想。

相關資料

860.柠檬水找零 https://programmercarl.com/0860.柠檬水找零.html

406.根据身高重建队列 https://programmercarl.com/0406.根据身高重建队列.html

452.用最少数量的箭引爆气球 https://programmercarl.com/0452.用最少数量的箭引爆气球.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值