【蓝蓝计算机考研算法】-day29-输出数组中重复的数字

72 阅读2分钟

43、输出数组中重复的数字

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

例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1。数据范围:0≤n≤10000 。
进阶:时间复杂度O(n) ,空间复杂度O(n)

示例

输入:[2,3,1,0,2,5,3]
输出:2
说明:2或者3 都是对的

思路

思路一: 穷举法

最简单的办法就是遍历数组的每个元素,然后将当前访问的数组与剩余的数组元素作大小比较,如果遇到相等的,则说明这个元素的值重复了,直接返回结果;如果不等,则继续遍历下一个数组元素。 

思路二: 优化版 思路一: 是一种比较笨的方法,是利用穷举法思想来解决问题的。显然,这种解法不是很好,因为它的时间复杂度是 O(n^2),算法的执行效率太低,如果有时间限制的话,肯定是通不过测试的。

根据题意可知,

  • 一元数组 nums 有 n 个数组元素,元素取值范围在 0~n-1 之间,而数组的下标范围也是 0 ~ n-1。
  • 我们可以将数组元素与其对应的下标值作大小比较,如果相等则跳过,遍历下一个数组元素;
  • 如果不等,则将该元素与以该元素值为下标所对应的数组元素进行比较, 如果相等,就表示找到了一个重复的元素,并返回该元素的值,不相等则将这两个元素值交换。

具体实现

思路一

#include<stdio.h>
int findRepeatNumber(int* nums, int numsSize) {
    if (nums == NULL || numsSize <= 0){
        printf("数组为空!");
        return -1;
    }
       
    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            if (nums[i] == nums[j]) {
                printf("%d", nums[i]);
                return nums[i];

            }
                
        }
    }
    return -1;
}
int main()
{
    int numbers[7] = { 2 ,3 ,1 ,0, 2, 5 ,3 };
    int length = 7;
    findRepeatNumber(numbers, length);
    return 0;
}

复杂度

空间复杂度O(1)---没有开辟新的存储空间。 时间复杂度O(n^2)---最坏情况,遍历完整个数组,两个for循环。

思路二

#include<stdio.h>
int findRepeatNumber(int* nums, int numsSize) {
    if (nums == NULL || numsSize <= 0)
        return -1;

    int i = 0;
    while (i < numsSize) {
        if (i == nums[i]) {
            i++;
            continue;
        }
        else {
            int tmp = nums[i];            //将a[i]赋值给临时变量tmp
            if (nums[i] == nums[tmp])      //如果相等,则返回重复元素值
            {
                printf("%d", nums[i]);
                return nums[i];
            } 
            else {                         //如果不等,则交换
                nums[i] = nums[tmp];
                nums[tmp] = tmp;
            }
        }
    }

    return -1;
}

int main()
{
    int numbers[7] = { 2 ,3 ,1 ,0, 2, 5 ,3 };
    int length = 7;
    findRepeatNumber(numbers, length);
    return 0;
}

复杂度

时间复杂度O(n) --- 有 n 个数组元素,循环n次 空间复杂度O(n)--- n代表有 n 个数组元素

运行结果

image.png