第一次完整的在线模拟,总体感觉就是思路清晰很重要,做完题目回头来看难度并不大,但如果能利用预处理,使得整体思路更加清晰,就可以使得编码更加轻松高效
836. Rectangle Overlap
难度:
Easy
思路:
给两个矩形,判断两个矩形是否重叠。
显然是分类讨论。看似很复杂,会有很多不同情况的样子,然而仔细想清楚,情况也很简单。
首先,确定下左侧的矩阵。右侧的矩阵若不重叠,只可能在上侧,下侧或者右侧,分类讨论一下这三种情况,其余情况下都重叠
代码:
/*
Author Owen_Q
*/
class Solution {
public:
bool isRectangleOverlap(vector<int>& rec1, vector<int>& rec2) {
if(rec1[0]>rec2[0])
swap(rec1,rec2);
if(rec2[1]>=rec1[3]||rec2[0]>=rec1[2])
return false;
if(rec2[3]<=rec1[1])
return false;
else
return true;
}
};
763. Partition Labels
难度:
Medium
思路:
给定一个字符串,要求所有相同字母必须在同一组,求最大划分方案。
这个显然就是个遍历字符串的模拟题,基本复杂度会在。
首先外层循环遍历每个划分的开始位置,内层循环寻找每个划分的长度。
然而内层循环会是个多轮的过程,每一轮都是去寻找当前长度情况下,最远的相同字母,然后去更新已有字母,增加长度,再次寻找新长度下的最远字母。直到当有一轮长度不变时,即可直到无新元素增加,即已经找到了一个分组。
代码:
/*
Author Owen_Q
*/
class Solution {
public:
vector<int> partitionLabels(string S) {
int n = S.size();
vector<int> re;
bool in[26];
memset(in,false,sizeof in);
for(int st = 0; st<n; st++)
{
int en = -1;
int newend = st;
in[S[st]-'a'] = true;
while(en!=newend)
{
//cout << en << "*" << newend << endl;
en = newend;
for(newend=n-1;newend>en;newend--)
{
if(in[S[newend]-'a'])
break;
}
for(int nowpos = en+1; nowpos < newend; nowpos++)
in[S[nowpos]-'a'] = true;
}
re.push_back(en-st+1);
//cout << en-st+1;
st = en;
}
return re;
}
};
代码提升:
其实这种情况下思路已经比较清晰了,精益求精,还是发现了一种更加优化的方法,那就是预处理。
扫描二维码关注公众号,回复:
8759830 查看本文章
既然已经知道这个算法的复杂度为,而且考虑到最远相同元素的位置十分重要,不如直接预处理出来,这样就是使得整个思路非常清晰。
在有了预处理数组的情况下,我们只需要一层循环即可解决。就是遍历每个元素,寻找最远重合位置,如果该位置与当前位置相同,即可得到一个分组,十分清晰,虽然这种与处理会稍稍影响运行时间,但这种代码十分容易理解,稳定性也十分高,不易受到输入数据的影响
代码:
/*
Author Owen_Q
*/
class Solution {
public:
vector<int> partitionLabels(string S) {
int n = S.size();
vector<int> re;
vector<int> np;
for(int i=0;i<n;i++)
{
for(int j=n-1;j>=i;j--)
{
if(S[i]==S[j])
{
np.push_back(j);
break;
}
}
}
int nowpos = 0;
int nexp = 0;
for(int st = 0; st<n; st++)
{
nexp = max(nexp,np[st]);
if(nexp == st)
{
re.push_back(st-nowpos+1);
nowpos = st+1;
}
}
return re;
}
};