【剑指Offer】【数组】3_数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
A1:因为数字有范围,所以可以把数字m放入下标为m的位置,若查找过程中发现num[m] == num[num[m]] 则存在重复数字 ====> 虽然有两重循环,但是每个数字最多只要交换两次即可,时间复杂度约等于O(n),但是要改变数组的结构
A2:创建长度为n+1的辅助数组,逐一把原数组的数字m复制到辅助数组的下标m处,当下标m处已有数字时,存在重复数字 ====> 时间复杂度O(n),空间复杂度O(n)
A3:从1~n的范围里只有n个数字,把1~n的数字从中间m数二分,若1~m的数字数目超过m,那么这一半的区间里一定包含重复数字 ====> 二分查找的思路,O(nlogn),不保证能找出所有重复的数字
//原数组上交换位置
class Solution { public: // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false bool duplicate(int numbers[], int length, int* duplication) { if((numbers == nullptr) || (length <= 0)) { return false; } for(int i = 0; i < length; i++) { if((numbers[i] < 0) || (numbers[i] > length - 1)) { return false; } } for(int i = 0; i < length ;i++) { while(numbers[i] != i) { if(numbers[i] == numbers[numbers[i]]) { *duplication = numbers[i]; return true; } int tmp = numbers[i]; numbers[i] = numbers[tmp]; numbers[tmp] = tmp; } } return false; } };
//辅助数组
class Solution { public: // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false bool duplicate(int numbers[], int length, int* duplication) { if((numbers == nullptr) || (length <= 0)) { return false; } for(int i = 0; i < length; i++) { if((numbers[i] < 0) || (numbers[i] > length - 1)) { return false; } } int tmp[100] = {-1}; for(int i = 0; i < length; i++) { if(tmp[numbers[i]] == numbers[i]) { *duplication = numbers[i]; return true; } tmp[numbers[i]] = numbers[i]; } return false; } };
//二分思想
太难了还不会写
相关题目:
中位数(小M给你一个长度为n的数组,我们定义median数为该数组从小到大排序后,下标为(n-1)/2的数字。下标从0开始,(n-1)/2表示整数除法,即向下取整。现在我们已经得到了一个初始的数组,我们希望这个数组的median数是一个给定数字x。所以我们需要加入一些数到数组中从而完成我们的目标。数组中的元素可以重复,请问,最少需要加入多少个数字才能达成这个目标。)
序列最小化(有一个长度为N的序列。一开始,这个序列是1, 2, 3,... n - 1, n的一个排列。对这个序列,可以进行如下的操作:每次选择序列中k个连续的数字,然后用这k个数字中最小的数字替换这k个数字中的每个数字。我们希望进行了若干次操作后,序列中的每个数字都相等。请你找出需要操作的最少次数。)
奇数位丢弃(对于一个由0..n的所有数按升序组成的序列,我们要进行一些筛选,每次我们取当前所有数字中从小到大的第奇数位个的数,并将其丢弃。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。)