找出数组中重复和出错的元素(C++(中等学习区)(有残留任务))

集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。

给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

示例 1:

输入: nums = [1,2,2,4]
输出: [2,3]

方法:排序后找到重复的元素,缺失的元素分为了两类,一类中间,一类在首尾,分别对两类获取值。

找缺失元素这里真的非常巧妙,原来是分为两种情况,一种是中间元素的缺失,不论是 12345变成11245,还是12455,缺失的部分都等于nums[i] + 1; 也就是排序后它的前面一个数加1,而当缺失的是首位的时候,测一下首尾,不是1或者最大值就把他换成最大值。

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
        vector<int>v;
        sort(nums.begin(),nums.end());
        //保存重复的元素
        int a=-1;
        //保存缺失的元素
        int b =-1;

        
        for(int i=0; i<nums.size()-1;i++)
        {
            //找到重复的元素
            if(nums[i]==nums[i+1])//有+1的时候就一定要考虑范围
            a=nums[i];
             
        
            //找到缺失的元素      
            if(nums[i+1]-nums[i]>1)
            b=nums[i]+1;
             

            //一旦ab被赋值之后就迅速退出循环
             if(a!=-1 && b!=-1)
             break;
        }

            //下面这两个一定要分开写!
            if(a!=-1 )
            {
                v.push_back(a);
                
            }
            if(b!=-1 )
            {
                v.push_back(b);              
            }

       
        //v.push_back(b);
    
        if(v.size()<2)
        {
            if(nums[0]!=1)  
            v.push_back(1);
            else
            v.push_back(nums.size());//把排在末尾的数插上
        }

        return v;
    }
};



第二种方法,这种方法简直绝了!把数学用到了极致!

class Solution:
    def findErrorNums(self, nums: List[int]) -> List[int]:
        S = sum(set(nums))
        return [sum(nums)-S ,len(nums)*(len(nums)+1)//2-S]

用set对原容器进行排序,并去除掉重复的数字,这样,sum(nums)-S就代表了被去掉的冲重复的数字是什么!
1+2+…+n=n*(n+1)/2 这个是求和公式,那么怎么求那个缺失的元素呢?
用真正的和减去用set排序之后的和,得出来的就是原本缺失掉的那个元素!

第三种方法:
借用下面这道题的解法:
https://blog.csdn.net/weixin_45479946/article/details/108371412

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {

        vector<int>v;
        //先找重复的数
        set<int>s;
        int n_sum=0;
        int s_sum = 0;
         for(int i=0; i<nums.size(); i++)
         {
             n_sum = n_sum+nums[i];
             s.insert(nums[i]);
         }
         for(set<int>::iterator it=s.begin();it!=s.end(); it++)
         {
             s_sum=s_sum+*it;
         }
        int rep = n_sum - s_sum;
        v.push_back(rep);
        //将所有数组中的数作为下标,置对应下标的数组中的数为负数。
        //被改变后的数组如果出现正数,那该正数的位置就代表未出现过得数组
        //巧妙的把数组的数转换为位置
        for(int i=0; i<nums.size(); i++)
        {
            //这里必须要加abs在nums[i]上!
            //因为一轮循环之后可能就把这个值变为负数了
            nums[abs(nums[i])-1] = -abs(nums[abs(nums[i])-1]);
        }
        
        for(int j=0; j<nums.size(); j++)
        {
            if(nums[j]>0)
            v.push_back(j+1);
        }

        return v;
        

    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,这是一个关于编程的问题,可以回答。您可以使用set.intersection()方法来查两个集合的交集。例如: ```python set1 = {1, 2, 3, 4, 5} set2 = {3, 4, 5, 6, 7} common_elements = set1.intersection(set2) print(common_elements) ``` 输出为: ``` {3, 4, 5} ``` 这样就可以到两个集合中的相同元素了。 ### 回答2: 要在Python中查两个集合中的相同元素,可以使用集合(set)的交集操作。 集合是一种无序且不重复数据结构,可以用来存储元素的集合。Python中的set类型和数学上的集合概念类似,可以进行并集、交集、差集等操作。 首先,我们可以分别将两个集合A和B定义为set类型的变量,例如: A = {1, 2, 3, 4} B = {3, 4, 5, 6} 然后,可以使用交集操作符 & 来获取两个集合的交集,即相同元素。代码如下: common_elements = A & B 最后,我们可以打印出交集的结果,代码如下: print(common_elements) 执行后,输出的结果为{3, 4},即集合A和集合B中共有的元素。 交集操作是一种非常简洁和高效的方法来查两个集合中的相同元素。在实际应用中,可以根据具体的需求和数据结构选择合适的操作方法。 ### 回答3: 要在Python中查两个集合中的相同元素,可以使用集合的交集运算。集合是Python中的一个内置数据类型,它没有顺序和重复元素。 假设我们有两个集合A和B,我们可以使用以下代码到它们的相同元素: ``` A = {1, 2, 3, 4} B = {3, 4, 5, 6} common_elements = A.intersection(B) ``` 在上面的代码中,`intersection()`是一种集合的交集操作。它将返回一个新的集合,其中包含A和B中共有的元素。在这个例子中,`common_elements`将是集合{3, 4}。 我们还可以将代码稍作修改以适应更多的集合。例如,我们想要查三个集合A、B和C中的相同元素: ``` A = {1, 2, 3} B = {2, 3, 4} C = {3, 4, 5} common_elements = A.intersection(B, C) ``` 在这个例子中,`common_elements`将是集合{3},因为只有元素3在A、B和C中都存在。 总结起来,要在Python中查两个或多个集合中的相同元素,可以使用集合的交集操作`intersection()`。这将返回一个新的集合,其中包含所有输入集合共有的元素

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值