题解 | #牛牛的和平年代#

牛牛的和平年代

http://www.nowcoder.com/practice/f60ad5b5594f4ad2ae1ee35d6e9e8f11

牛牛的和平年代

问题描述
我们定义一个整数可重集合是好的,当且仅当对于集合中任意两个元素 a, b () ,所有满足 的元素 c 都在集合中出现过。
现在,给你一个数组 mSet,你需要做的是,对于这个数组的每一个前缀,判断这个前缀是不是一个好的集合。所以,你将计算出的是一个数组,为布尔类型。
示例
输入:[3,5,4,6]
返回值:[true,false,true,true]
说明:第一个前缀只有一个元素3,按照好的集合的定义,它显然是连续的。
第二个前缀有一个3和一个5,位于3和5之间的元素4却不在集合中,所以它不是连续的。
第三个前缀添加了一个4,弥补了第二个集合缺少4的问题,所以它是好的。
第四个前缀新增了一个6,依旧连续。

方法一

思路分析

      设置一个数组,,每次添加一个元素进去构成该位置下的前缀,然后对前缀数组元素进行排序,如果两个前后的数不同而且相差不为1,那么可以判断前缀不连续,否则表示该位置下的前缀连续,不断的添加新元素到前缀数组中,直到添加完所有的元素。

图解




C++核心代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 检查数组的每个前缀是不是一个好的集合
     * @param mSet int整型vector 
     * @return bool布尔型vector
     */
    vector<bool> continuousSet(vector<int>& mSet) {
        // write code here
        int n=mSet.size();
        vector<bool> res(n,false);
        if (n==0) return res;
        vector<int> array;
        for(int i=0;i<n;i++)
        {
            array.push_back(mSet[i]);//每次将一个元素放入array
            sort(array.begin(),array.end());//对前缀排序
            int ans=0;
            int nn=array.size();
            for(int j=1;j<nn;j++)
            {
                if(array[j]-array[j-1]!=1&&array[j]!=array[j-1])
                {////对排序的前缀判断是否连续,如果两个前后的数不同而且相差不为1,那么可以判断前缀不连续
                    res[i]=false;
                    ans=1;
                }
            }
            if(ans==0) res[i]=true;
        }
      return res;   
    }
};
复杂度分析
  • 时间复杂度:首先循环遍历给定数组,每次添加一个元素进行排序,时间复杂度为$O(n \log n)$,每次排序后的比较次数为n次,总的时间复杂度为
  • 空间复杂度:借助于一个辅助数组存储前缀元素,空间复杂度为$O(n)$

方法二

思路分析

      方法一中需要对添加元素后的前缀数组进行重新排序,而后对排序后的前缀元素进行比较,前后的元素如果不相同那么必须相差1,这其中对数组的排序与比较会花费较多的时间,因此将每次添加的数组元素存储到map结构中,并且记录到当前情况下的前缀中的最大值与最小值,如果到当前位置添加的不同元素个数等于最大值减去最小值加一,那么证明该位置下的前缀数组是连续的。

C++核心代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 检查数组的每个前缀是不是一个好的集合
     * @param mSet int整型vector 
     * @return bool布尔型vector
     */
    vector<bool> continuousSet(vector<int>& mSet) {
        // write code here
        int n=mSet.size();
        vector<int> dp(n,0);//用于存储set(mSet[:i])的长度
        vector<bool> res(n,false);
        if (n==0) return res;
        dp[0]=1;
        for(int i=1;i<n;i++)
        {
            vector<int>::const_iterator First = mSet.begin();
            vector<int>::const_iterator Second = mSet.begin() + i+1;
            vector<int> a(First, Second);
            dp[i]=count(a);
        }
        int set_min=mSet[0];
        int set_max=mSet[0];
        res[0]=true;
        for(int i=1;i<n;i++)
        {
            set_min=min(set_min,mSet[i]);
            set_max=max(set_max,mSet[i]);
            if(set_max-set_min+1==dp[i])//前缀是否连续
                res[i]=true;
            else res[i]=false;
        }
      return res;   
    }
    int count(vector<int>& a) 
    {
	sort(a.begin(),a.end());//快速排序
	int count = 1;//统计不重复元素数
	for(int i = 1;i<a.size();i++) {//第一个元素必然要计数
		if(a[i]!=a[i-1]) {//和前一个元素重复则不计数
			count++;
		}
	}
	return count;
}
  
};
复杂度分析
  • 时间复杂度:计算数组中从开始位置到不同位置下的不重复元素的个数,时间复杂度为$O(n^2 \log n)$,遍历数组元素时找到当前位置下的前缀元素中的最大值与最小值,因此时间复杂度为$O(n^2 \log n)$
  • 空间复杂度:借助于一个大小为$n$的数组存储给定数组中开始位置到当前位置的不重复的元素个数,空间复杂度为$O(n)$
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 长得好看会提高面试通过率吗? #
4018次浏览 46人参与
# 离家近房租贵VS离家远但房租低,怎么选 #
16907次浏览 137人参与
# 米连集团26产品管培生项目 #
7309次浏览 226人参与
# 春招至今,你的战绩如何? #
15816次浏览 145人参与
# 你的实习产出是真实的还是包装的? #
3098次浏览 53人参与
# 沪漂/北漂你觉得哪个更苦? #
1553次浏览 41人参与
# 巨人网络春招 #
11527次浏览 224人参与
# HR最不可信的一句话是__ #
1091次浏览 32人参与
# AI面会问哪些问题? #
946次浏览 23人参与
# 你做过最难的笔试是哪家公司 #
1247次浏览 22人参与
# AI时代,哪个岗位还有“活路” #
2853次浏览 51人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152905次浏览 889人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
8021次浏览 43人参与
# XX请雇我工作 #
51155次浏览 171人参与
# 简历第一个项目做什么 #
32148次浏览 361人参与
# 简历中的项目经历要怎么写? #
311051次浏览 4265人参与
# 投格力的你,拿到offer了吗? #
178339次浏览 891人参与
# 你最满意的offer薪资是哪家公司? #
76981次浏览 375人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187605次浏览 1123人参与
# AI时代,哪些岗位最容易被淘汰 #
64760次浏览 890人参与
# 如果重来一次你还会读研吗 #
230018次浏览 2011人参与
# 正在春招的你,也参与了去年秋招吗? #
364353次浏览 2642人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务