56. 合併區間
題目連結:https://leetcode.cn/problems/merge-intervals/
題目難度:中等
文章講解:https://programmercarl.com/0056.合併區間.html
影片講解:https://www.bilibili.com/video/BV1wx4y157nD
題目狀態:有思路,嘻嘻🤣
思路:
首先,按照每個區間開頭的前後順序進行排列,然後定義一個vector<int>
型別的變數來儲存我們合併的區間,迴圈遍歷每個區間,判斷當前合併的區間結尾是否大於等於下一個區間的開頭。若大於,表示可以將該區間合併起來,否則,表明下面的區間不會和已經合併的區間有重疊了,將其存入返回變數,並改變其為下一個區間,繼續遍歷,直到遍歷完。
程式碼:
點選檢視程式碼
class Solution {
public:
static bool cmp(const vector<int> &a, const vector<int> &b) {
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), cmp);
vector<vector<int>> res;
vector<int> temp = intervals[0];
for(int i = 1; i < intervals.size(); ++i) {
if(temp[1] >= intervals[i][0]) {
temp[1] = max(temp[1], intervals[i][1]);
} else {
res.push_back(temp);
temp = intervals[i];
}
}
res.push_back(temp);
return res;
}
};
738. 單調遞增的數字
題目連結:https://leetcode.cn/problems/monotone-increasing-digits/
題目難度:中等
文章講解:https://programmercarl.com/0738.單調遞增的數字.html
影片講解:https://www.bilibili.com/video/BV1Kv4y1x7tP
題目狀態:沒有思路,不嘻嘻😭
思路:
從後往前遍歷(這是關鍵),判斷前一位數是否大於後一位數:
- 若大於,將前一位數減1,這表明前一位數已經大於後面的數了,只能將前面的數減1,之後在將後面的數置為9
- 若不大於,則向前繼續遍歷。
注意要記錄最後一個減1的位數的下一個位數,之後要統一將其後面的數置為9.
程式碼:
點選檢視程式碼
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
int flag = strNum.size();
for(int i = strNum.size() - 1; i > 0; --i) {
if(strNum[i - 1] > strNum[i]) {
flag = i;
strNum[i - 1]--;
}
}
for(int i = flag; i < strNum.size(); ++i) strNum[i] = '9';
return stoi(strNum);
}
};
968. 監控二叉樹
題目連結:hhttps://leetcode.cn/problems/binary-tree-cameras/
題目難度:困難
文章講解:https://programmercarl.com/0968.監控二叉樹.html
影片講解:https://www.bilibili.com/video/BV1SA411U75i
題目狀態:看完題目就知道了,要看題解了😭
思路:
首先,明確遍歷順序,要用後序遍歷來實現從下往上遍歷,因為要避免葉子節點安裝監控(這種情況下會產生最大的浪費)。
之後,將節點的狀態分為以下幾種:
- 本節點沒有被攝像頭覆蓋,用
0
表示; - 本節點上安裝攝像頭,用
1
表示; - 本節點被攝像頭覆蓋,用
2
表示。
注意:遞迴結果是判斷該節點是否為nullptr
來結束的,通常節點為nullptr
時說明我們遍歷到了葉子節點的下面,那我們要給空節點設定一個狀態,為了符合下面判斷的邏輯,我們要將空節點設定為狀態2
(儘管並沒有被覆蓋),因為若我們將空節點設定為沒有被覆蓋的狀態,我們就需要將葉子節點設定為狀態1
,此時就出現了最大浪費。
下面我們進行單層的邏輯:
- 本節點的左右孩子都有被覆蓋,即
left == 2 && right == 2
此時該節點沒有被覆蓋,因此該節點的狀態為0
。 - 本節點的左右孩子中至少有一個是沒有被覆蓋的,即
left == 0 || right == 0
此時該節點需要對下面的孩子進行覆蓋,因此需要將攝像頭的個數加一,然後返回狀態1
。 - 本節點的左右孩子中至少一個安裝了攝像頭,即
left == 1 || right == 1
此時該節點處於被覆蓋狀態,返回狀態2
。
注意:當遍歷完之後,若發現返回的根結點的狀態是0
,攝像頭需要加一。
程式碼:
點選檢視程式碼
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int res;
int traversal(TreeNode *cur) {
if(cur == nullptr) return 2;
int left = traversal(cur->left);
int right = traversal(cur->right);
if(left == 2 && right == 2) {
return 0;
}
if(left == 0 || right == 0) {
res++;
return 1;
}
if(left == 1 || right == 1) {
return 2;
}
return -1;
}
int minCameraCover(TreeNode* root) {
res = 0;
if(traversal(root) == 0) {
res++;
}
return res;
}
};