[剑指offer] 03数组中重复的数字

题目

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

示例:

输入:

[2, 3, 1, 0, 2, 5, 3]

输出:2 或 3

限制:

2 <= n <= 10000

题解

C语言

方法一:

  使用一个同等大小的数组计数,遍历输入的数组,在计数数组中计数出现的次数,当次数累计到 2 时输出该值。

int findRepeatNumber(int* nums, int numsSize){
    int *arr;   //计数数组声明
    arr = (char*)malloc(numsSize*sizeof(int));
    memset(arr,0,sizeof(int)*numsSize);
    for(int i = 0; i < numsSize; i++){
        arr[nums[i]] ++;
        if(arr[nums[i]] > 1)
            return nums[i];
    }
    return -1;
}

  该方法:执行用时:44 ms, 在所有 C 提交中击败了63.99%的用户,内存消耗:10.9 MB, 在所有 C 提交中击败了9.45%的用户。

方法二:

  数组长 n ,取值范围也是 0~n-1,所以只需让数据回到原来应该在的位置,当某一个数回去时发现自己位置上已经有人了的话就找到了重复的数。

int findRepeatNumber(int* nums, int numsSize){
    int now;
    int temp;
    while(1){
        for (int i = 0; i < numsSize; i++){  //找第一个编号和内容不匹配的数
            if(nums[i] == i)
                continue;
            else{
                now = nums[i];
                nums[i] = -1;
                break;
            }
        }
        while (1){ //循环迭代到出结果或者一个内循环换完了
            if(nums[now] == now)  //结束条件
                return now;
            else{
                temp = nums[now];
                nums[now] = now;
                now = temp;
                if (now == -1)  // 构成了一个循环
                    break;
            }
        }
    }
}

  该方法:执行用时:执行用时:40 ms, 在所有 C 提交中击败了89.62%的用户,内存消耗:10 MB, 在所有 C 提交中击败了84.40%的用户。

总结

  方法二在 leetcode上的提交测试中无论是内存消耗还是执行用时都是要更优的。

你可能感兴趣的:([剑指offer] 03数组中重复的数字)