题解 | #找出重复的数#

找出重复的数

http://www.nowcoder.com/practice/6973953f1ddb43f897ca23ec60389e87

思路:

题目很短,主要信息为:

  • 序列a中的数字为1到n的整数,只有一个数字重复
  • 时间复杂度为 O(n),额外空间复杂度为 O(1)。

方法一:求和相减

具体做法:
1到n的整数之和为sum=图片说明
若a中重复的数字为i,则a中所有数字之和可以表示为a_sum=图片说明
这样就能够得到重复的数字为a_sum-sum=i。
图解示例:
图片说明

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int 
     * @param a intvector 
     * @return int
     */
    int search(int n, vector<int>& a) {
        // write code here
        int a_sum=0;//a_sum保存序列a中所有数之和
        for(int i=0;i<=n;i++)
        {
            a_sum+=a[i];
        }
        int sum=0;//sum保存1到n整数之和
        for(int i=1;i<=n;i++)
        {
            sum+=i;
        }
        int result=a_sum-sum;//得到重复值
        return result;
    }
};

复杂度分析:

  • 时间复杂度:图片说明 ,一层遍历。
  • 空间复杂度:图片说明 ,只使用了常数空间。

方法二:异或法

具体做法:
记1到n中所有数字的异或为y=1^2^3……^n;
若序列a中重复的数字为i,记序列a中所有数字的异或为x=1^2^3……^n^i。
因为序列a中有两个一样的数字i,i^i=0,相当于把i抵消了,即序列a所有数字的异或为x=1^2^3……(i-1)^(i+1)……^n
因此要求重复值,只需要将x和y异或,x^y=i;

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int 
     * @param a intvector 
     * @return int
     */
    int search(int n, vector<int>& a) {
        // write code here
        int x=0;//计算序列a的异或
        int y=0;//计算1到n的异或
        for(int i=0;i<=n;i++)//
        {
            x=x^a[i];
        }
        for(int i=1;i<=n;i++)
        {
            y=y^i;
        }
        return x^y;//得到重复的数字
    }
};

复杂度分析:

  • 时间复杂度:图片说明 ,只进行了一层遍历。
  • 空间复杂度:图片说明 ,只占用了常数空间。
全部评论

相关推荐

02-10 12:23
已编辑
新余学院 C++
采集想要offer:专业技能那里要一条一条的列出来吧,感觉你项目很厉害了,但是如果你不写技术栈面试官对你项目不太懂的话都没办法问你八股😂C++都是基架岗,都是一群9✌🏻在卷,我觉得你要是有时间学个go把MySQL和redis写上去找个开发岗吧
点赞 评论 收藏
分享
01-18 09:26
已编辑
门头沟学院 Java
王桑的大offer:建议中间件那块写熟悉即可,写掌握 面试包被拷打到昏厥
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务