【剑指offer 03.数组中的重复数字】

剑指offer 03.数组中的重复数字

题目

找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

链接:https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

题解

解法1:暴力循环

解法分析

使用双重循环,对每一个遍历到的元素,遍历其后的元素,判断是否与当前元素相等,若相等,直接返回,不相等继续查找直到找到相等情况或者遍历完数组。

边界条件与特殊值分析
  1. nums.size()==0,应当返回-1
  2. 数组中不存在重复值,应当返回-1
复杂度分析

时间复杂度 O(n^2)
空间复杂度 O(1)

代码
int findRepeatNumber(vector<int>& nums) {
    //force
    //复杂度 n^2
    //使用双重循环,对每一个数寻找后面是否有相同项
    for(int i=0;i<nums.size();i++)
    {
        for(int j=i+1;j<nums.size();j++)
        {
            if(nums[j]==nums[i])return nums[i];
        }
    }
    return -1;
}
可能存在的问题

暂无

解法2:排序+遍历

解法分析

使用排序算法进行排序后,进行遍历,若nums[i]==nums[i+1],则返回nums[i],否则直到遍历到数组下标到达该数组长度为止。
排序算法使用复杂度为nlogn的算法,可以使用快速排序

边界条件与特殊值分析
  1. nums.size()==0,应当返回-1
  2. 数组中不存在重复值,应当返回-1
复杂度分析

时间复杂度 O(nlogn)
空间复杂度 O(n)

代码
int findRepeatNumber(vector<int>& nums) {
    //sort & linear search
	//待补充
    return -1;
}
可能存在的问题

暂无

解法3:简易Hashmap

解法分析

因数组内元素大小在 [0,n-1] 范围内,故尝试使用长度为 n 的数组hash,以下标作为hashmap的key,将数组值作为出现次数,即value,形成键值对,遍历过程中,若 hash[num[i]]==0,则将hash[num[i]]+1,若hash[num[i]]=1,则返回重复值。

边界条件与特殊值分析
  1. nums.size()==0,应当返回-1
  2. 数组中不存在重复值,应当返回-1
复杂度分析

时间复杂度 O(n)
空间复杂度 O(n)

代码
int findRepeatNumber(vector<int>& nums) {
    //hashmap
    int sizeOfNums=nums.size();
    vector<int>hash(sizeOfNums);
    for(int i=0;i<sizeOfNums;i++)
    {
        if(hash[nums[i]]==1)return nums[i];
        else hash[nums[i]]++;
    }
    return -1;
}
可能存在的问题

暂无

解法4:数组元素交换归位

解法分析

对于nums数组,进行遍历,对nums[i],若nums[i]==i,则进行下一位比较,否则,若nums[nums[i]]!=nums,交换nums[i]与nums[nums[i]],并就继续内循环判断,直到相等,否则,输出重复值,比如对于{2,3,1,0,2,5,3},进行推导尝试

边界条件与特殊值分析
  1. nums.size()==0,应当返回-1
  2. 数组中不存在重复值,应当返回-1
复杂度分析

时间复杂度 O(n)
空间复杂度 O(1)

代码
int findRepeatNumber(vector<int>& nums) {
    //swap
    for(int i=0;i<nums.size();i++)
    {
        while(nums[i]!=i)
        {
            if(nums[i]==nums[nums[i]])return nums[i];
            else swap(nums[i],nums[nums[i]]);
        }
    }
    return -1;
}
可能存在的问题

暂无

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值