目录
讀題
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++的語法真的沒有到非常理解
其實整體思路就三個部分
- 利用左邊界進行排序
- 遍例數組,假設左邊界與下一個的右邊界不重合則result++,否則更新右邊界,取右邊界最小的進行更新。
- return result.
860.柠檬水找零 - 實作
思路
- 用兩個個變數去紀錄5 與 10
- 遍歷數列
- 5 變數5加加
- 10 ,變數5不為零,則減減 ,並且10 ++
- 如果不滿足直接return false
- 20
- 優先策略 10減減 5 減減
- 次優策略 5 -= 3;
- 如果不滿足則直接return false ,
- 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.根据身高重建队列 - 實作
思路
- 先確認身高由高到低進行排序
- 身高一樣則用k進行低到高的排序
- 建立一個q數組
- 根據k,將原數組根據k的規格進行插入操作
- 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.用最少数量的箭引爆气球 - 實作
思路
- 利用左邊界進行排序
- 遍例數組,假設左邊界與下一個的右邊界不重合則result++,否則更新右邊界,取右邊界最小的進行更新。
- 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