题目描述
我们定义一个整数可重集合是好的,当且仅当对于集合中任意两个元素 a, b (a≤b) ,所有满足 a≤c≤b 的元素 c 都在集合中出现过。
现在,给你一个数组 mSet,你需要做的是,对于这个数组的每一个前缀,判断这个前缀是不是一个好的集合。所以,你将计算出的是一个数组,为布尔类型。
方法一:暴力求解
求解思路
对于本题目的求解,我们首先对输入的数据定义一个数组,每次添加一个元素进去构成该位置的前缀。然后对数组进行排序,如果前后两个数不同,而且不相差1,那么可以得知这个位置是不连续的,否则为连续的。按照上述的思路,对输入进行遍历,最后即可求出相应的答案。
解题代码
class Solution {
public:
vector<bool> continuousSet(vector<int>& mSet)
{
int n = mSet.size(); // 存储mset的大小
vector<bool> myres(n,false); // 存储结果
if (n==0) return myres; // 直接返回结果
vector<int> temp;
for(int i=0;i<n;i++)
{
temp.push_back(mSet[i]);
if(iscontinue(temp)) // 按照题目的思路进行判断
myres[i]=true;
}
return myres; // 返回结果
}
bool iscontinue(vector<int> temp)
{
sort(temp.begin(),temp.end()); // 快排
for(int m = 1;m <temp.size();m++)
{
if(temp[m] - temp[m - 1] != 1 &&temp[m] !=temp[m - 1])
{
return false; // 不连续,返回false
}
}
return true; // 连续,返回true
}
};复杂度分析
时间复杂度:一层循环加快排,因此时间复杂度为
空间复杂度:使用数组temp[n],因此空间复杂度为
方法二:优化思想求解
求解思路
基于方法一,我们发现每次添加输入的数值以后都要进行重新排序,因此我们对方法一进行优化,设置临时变量来存储当前数组的最大最小值,并且新加入元素后只对临时变量进行更新即可。然后其他思路同方法一,对辅助数组进行排序,进行相差1的判断,最后输出结果即可。
解题代码
class Solution {
public:
vector<bool> continuousSet(vector<int>& mSet)
{
int n=mSet.size(); // 存储mset的大小
vector<bool> myres(n,false); // 存储大小
if (n==0) return myres;
map<int,int> temp;
int mymin=mSet[0]; // 声明变量记录最小值
int mymax=mSet[0]; // 声明变量记录最大值
myres[0]=true;
temp[mSet[0]]++;
for(int i=1;i<n;i++)
{
mymin=min(mymin,mSet[i]); // 记录最小值
mymax=max(mymax,mSet[i]); // 记录最大值
temp[mSet[i]]++; // 更新临时变量
if(mymax-mymin+1==temp.size())
myres[i]=true;
else myres[i]=false;
}
return myres; // 返回结果
}
};复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:使用map型的temp,因此空间复杂度为

京公网安备 11010502036488号