剑指offer(C++)-JZ3:数组中重复的数字(算法-排序)

简介: 剑指offer(C++)-JZ3:数组中重复的数字(算法-排序)

题目描述:

在一个长度为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都是对的  

解题思路:

本题是排序类题目,四种解题思路:

1)暴力法


      双循环遍历,找到重复数字返回。时间复杂度O(n^2),空间复杂度O(1)。


2)排序遍历法


      用快速排序将数组排序,再遍历搜索。时间复杂度O(nlogn),空间复杂度O(1)。


3)哈希表


      用哈希表判断数字是否重复,可以用哈希set或者哈希map。哈希表查询O(1),所以只需遍历一轮即可完成。时间复杂度O(n),空间复杂度O(n)。


4)下标哈希法


      将数组下标作为哈希键,比如数字2就把它放在数组下标2的位置,原先下标2位置的数字移动到数字2本来的位置,完成交换;依次类推,直到某次交换发现数字x和下标x的数字冲突了,说明找到重复值了;最坏的情况就是没有重复数字,把所有下标都遍历交换过一轮。时间复杂度O(n),空间复杂度O(1)。


      注意:应用该方法的前提是如题目给定的条件那般,数字大小范围在0到n-1之间,不然就越界了。

测试代码:

1)暴力法

class Solution {
public:
    // 寻找重复数据
    int duplicate(vector<int>& numbers) {
        int size= int(numbers.size());
        for (int i = 0; i < size; ++i){
            for (int j = i + 1; j < size; ++j){
                if (numbers[i] == numbers[j])
                    return numbers[i];
            }
        }
        return -1;
    }
};

2)排序遍历法

class Solution {
public:
    // 寻找重复数据
    int duplicate(vector<int>& numbers) {
        // 快排
        sort(numbers.begin(),numbers.end());
        int size = int(numbers.size());
        // 寻找重复值
        for(int i = 1; i <size; ++i){
            if(numbers[i] == numbers[i - 1])
                return numbers[i];
        }
        return -1;
    }
};

3)哈希表

class Solution {
public:
    // 寻找重复数据
    int duplicate(vector<int>& numbers) {
        // 哈希set
        unordered_set<int> us;
        int size = int(numbers.size());
        for(int i = 0; i < size; ++i){
            if(us.count(numbers[i]))
                return numbers[i];
            else
                us.insert(numbers[i]);
        }
        return -1;
    }
};

4)下标哈希法

class Solution {
public:
    // 寻找重复数据
    int duplicate(vector<int>& numbers) {
        // 下标哈希法
        int size = int(numbers.size());
        for(int i = 0; i < size;){
            if(numbers[i]==i)
                i++;
            else{
                if(numbers[numbers[i]] == numbers[i])
                    return numbers[i];
                else{
                    swap(numbers[numbers[i]], numbers[i]);
                }
            }
        }
        return -1;
    }
};


相关文章
|
9天前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
|
10天前
|
机器学习/深度学习 运维 算法
基于非支配排序遗传算法NSGAII的综合能源优化调度(Matlab代码实现)
基于非支配排序遗传算法NSGAII的综合能源优化调度(Matlab代码实现)
基于非支配排序遗传算法NSGAII的综合能源优化调度(Matlab代码实现)
|
11天前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
|
1月前
|
机器学习/深度学习 算法 安全
【无人机3D路径规划】基于非支配排序遗传算法NSGAII的无人机3D路径规划研究(Matlab代码实现)
【无人机3D路径规划】基于非支配排序遗传算法NSGAII的无人机3D路径规划研究(Matlab代码实现)
132 1
|
18天前
|
机器学习/深度学习 算法 安全
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)
|
1月前
|
机器学习/深度学习 算法 安全
【优化调度】基于matlab非支配排序遗传算法求解车辆充电调度优化问题研究(Matlab代码实现)
【优化调度】基于matlab非支配排序遗传算法求解车辆充电调度优化问题研究(Matlab代码实现)
|
7天前
|
供应链 算法 Java
【柔性作业车间调度问题FJSP】基于非支配排序的多目标小龙虾优化算法求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
【柔性作业车间调度问题FJSP】基于非支配排序的多目标小龙虾优化算法求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
|
12天前
|
存储 算法 搜索推荐
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
专攻软考高频算法,深度解析二分查找、堆排序、快速排序核心技巧,对比九大排序算法,配套动画与真题,7天掌握45%分值模块。
68 0
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
|
4月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
107 2
|
5月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。

热门文章

最新文章