数组中重复的数字_牛客题霸_牛客网 (nowcoder.com)
【排序法】思路和代码:
- 对数组进行排序。
- 遍历排序后的数组,如果当前元素与下一个元素相等,则找到了重复数字,返回该数字。
- 如果遍历完数组都没有找到重复数字,则返回-1。
时间复杂度:O(nlogn) (取决于排序算法的复杂度) 空间复杂度:O(1)(原地排序,没有使用额外的空间)
int findDuplicate(vector<int>& nums) { sort(nums.begin(), nums.end()); for (int i = 1; i < nums.size(); i++) { if (nums[i] == nums[i - 1]) { return nums[i]; } } return -1; }
【哈希表法】思路和代码:
- 创建一个哈希表(或者使用unordered_set),用于存储已经遍历过的数字。
- 遍历数组,对于每个数字,检查哈希表中是否已经存在该数字。
- 如果存在,则找到了重复数字,返回该数字。
- 如果不存在,则将该数字添加到哈希表中。
- 如果遍历完数组都没有找到重复数字,则返回-1。
时间复杂度:O(n) 空间复杂度:O(n)(存储哈希表的额外空间)
class Solution { public: int duplicate(vector<int>& nums) { // write code here unordered_set<int> seen; // 创建一个哈希表用于存储已经遍历过的数字 for (int num : nums) { if (seen.count(num) > 0) { // 如果当前数字已经存在于哈希表中,即找到了重复数字 return num; } seen.insert(num); // 将当前数字添加到哈希表中 } return -1; // 数组中没有重复数字 } };
(最佳)【下标法】思路和代码:
该问题可以通过下标法来解决,通过对数组进行遍历,将数字按照其值与下标对应的关系进行交换,使得每个位置上的数字与其下标一致。当发现某个位置上的数字与下标不一致时,即找到了一个重复的数字。
具体步骤如下:
- 从头到尾依次扫描数组中的每个数字。
- 当扫描到下标为i的数字nums[i]时,首先判断nums[i]是否等于i。
- 若相等,则继续扫描下一个数字。
- 若不相等,则将nums[i]与nums[nums[i]]的数字进行交换,即将nums[i]放到正确的位置上。
- 交换后,再次判断当前位置上的数字nums[i]是否等于i。
- 若相等,则继续扫描下一个数字。
- 若不相等,则判断nums[i]与nums[nums[i]]的数字是否相等。
- 若相等,则找到了重复数字nums[i],返回该数字。
- 若不相等,则继续交换,重复步骤3。
- 如果遍历完数组都没有找到重复数字,则返回-1。
时间复杂度:O(n) 空间复杂度:O(1)(原地操作,没有使用额外的空间)
int findDuplicate(vector<int>& nums) { for (int i = 0; i < nums.size(); i++) { while (nums[i] != i) { // 当前位置的数字与下标不一致时执行交换操作 if (nums[i] == nums[nums[i]]) { // 发现重复数字 return nums[i]; } // 交换当前位置的数字nums[i]与应该在该位置上的数字nums[nums[i]] swap(nums[i], nums[nums[i]]); } } return -1; // 数组中没有重复数字 }