763.划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
先定义一个哈西数组 统计每个字母出现的最远位置 a=26也行
从头到尾遍历 先用right记录第一个字符的最远位置 然后一直往后遍历并更新最远位置right
当i=right的时候说明找到了第一组结果,返回长度 并接着记录下一组
class Solution {
public:
vector<int> partitionLabels(string S) {
int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
hash[S[i] - 'a'] = i;
}
vector<int> result;
int left = 0;
int right = 0;
for (int i = 0; i < S.size(); i++) {
right = max(right, hash[S[i] - 'a']); // 找到字符出现的最远边界
if (i == right) {
result.push_back(right - left + 1);
left = i + 1;
}
}
return result;
}
};
56. 合并区间
给出一个区间的集合,请合并所有重叠的区间。
按照左区间进行排序
先把第一个区间放结果集里
从第二个区间开始遍历
先看这个区间和上一个区间 也就是结果集里的区间是否重叠
不重叠就把这个区间放到结果集里
重叠的话就改变结果集的右区间 取两个区间的最大右区间
class Solution {
public:
static bool cmp(vector<int> a,vector<int> b){
return a[0]<b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> result;
sort(intervals.begin(),intervals.end(),cmp);
result.push_back(intervals[0]);
for(int i=1;i<intervals.size();i++){
if(result.back()[1]>=intervals[i][0]){
result.back()[1]=max(result.back()[1],intervals[i][1]);
}else{
result.push_back(intervals[i]);
}
}
return result;
}
};
738.单调递增的数字
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
将数字转变成字符串类型 方便对数字上的每一位进行遍历
flag初始值赋值为最后一位数的下一位
从最后一个数往回遍历 如果前一个数比后一个数大 就把前一个数-1 flag指向此数
最后把flag指向的数的后边全变成9
为什么不在第一个循环直接赋值9:
1000为例子 -> 会出现0900
为什么要一开始给flag赋值:
因为1234的情况 flag在第一个循环没动 以防止第二个循环把1234变成9999
class Solution {
public:
int monotoneIncreasingDigits(int N) {
string strNum = to_string(N);
// flag用来标记赋值9从哪里开始
// 设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
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);
}
};