56.合併區間
題目連結 文章講解 影片講解
思路:
按左區間排序;
遍歷所有區間,如果當前區間的左邊界小於等於上一個區間的右邊界,則合併區間(新區間的左邊界為上一個區間的左邊界,新區間的右邊界為上一個區間的有邊界和當前區間有邊界中較大的一個)
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> result;
sort(intervals.begin(), intervals.end(), [](vector<int>& lhs, vector<int>& rhs){ return lhs[0] < rhs[0]; });
for(int i = 0; i < intervals.size(); ++i) {
// 合併區間
if(i > 0 && intervals[i][0] <= intervals[i - 1][1]) {
intervals[i][0] = intervals[i - 1][0];
intervals[i][1] = max(intervals[i - 1][1], intervals[i][1]);
} else {
// 區間不重複,將上一個區間新增到結果集中
if(i > 0) {
result.push_back(intervals[i - 1]);
}
}
// 遍歷到最後一個區間,直接將其新增到結果集中
if(i == intervals.size() - 1) result.push_back(intervals[i]);
}
return result;
}
};
738.單調遞增的數字
題目連結 文章講解 影片講解
暴力解法
評價-->超時
class Solution {
public:
int monotoneIncreasingDigits(int n) {
while(n) {
if(isIncreasing(n)) return n;
n--;
}
return -1;
}
bool isIncreasing(int n) {
int pre = n % 10;
while(n) {
n = n / 10;
int cur = n % 10;
if(pre < cur) return false;
pre = cur;
}
return true;
}
};
貪心
思路:
從後向前遍歷,如果當前數字比前一位數字小,則前一個數字減一(借位),當前位變為9
特殊情況1000,如果不做處理的話,從後向前遍歷會得到結果0900,轉為數字後是900,不是最大的。
所以用flag記錄當前需要邊為9的索引,從索引開始向右全部變為9,因為右邊必須要大於等於左邊,所以應全部變為9
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string s_n = to_string(n);
int flag = s_n.size();
for(int i = s_n.size() - 1; i > 0; --i) {
if(s_n[i] < s_n[i - 1]) {
flag = i;
s_n[i - 1]--;
}
}
// 將flag向右的所有數字變為9
for(int i = flag; i < s_n.size(); ++i) {
s_n[i] = '9';
}
return stoi(s_n);
}
};