zoukankan      html  css  js  c++  java
  • leetcode 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字

    找出数组中重复的数字。

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

    示例 1:

    输入:
    [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3

    限制:

    2 <= n <= 100000

    解法一:计数排序

    思路:

    利用计数排序,在统计次数的时候判断出现次数是否大于1,如果大于1直接返回该数

     1 class Solution {
     2     public int findRepeatNumber(int[] nums) {
     3         int len = nums.length;
     4         // 计数排序,如果数量大于1则返回
     5         int[] counts = new int[len];
     6         for(int i = 0; i < len; i++){
     7             counts[nums[i]]++;
     8             if(counts[nums[i]] > 1){
     9                 return nums[i];
    10             }
    11         }
    12         return -1;
    13     }
    14 }

    leetcode 运行时间为2ms, 空间为45.9MB

    复杂度分析:

    时间复杂度:计数排序,但是不需要统计完,所以平均时间复杂度为O(n/2)

    空间复杂度:需要创建一个和nums数组等大的数组,所以空间复杂度为O(n)

    解法二:

    思路来源:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/yuan-di-zhi-huan-shi-jian-kong-jian-100-by-derrick/

    在元素不重复的情况下,但数组有序时,每个元素所在的位置和这个元素的值相等。所以我们遍历数组,把当前元素放到正确的位置,也就是以这个元素为下标的位置,把当前元素和他正确的位置的元素进行交换。重新安排位置的过程中,肯定就会有元素重复的情况。返回即可

     1 class Solution {
     2     public int findRepeatNumber(int[] nums) {
     3         int len = nums.length;
     4 
     5         for(int i = 0; i < len; i++){
     6             // 如果当前元素不在正确的位置
     7             if(nums[i] != i){
     8                 // 如果重复,直接返回
     9                 if(nums[i] == nums[nums[i]]){
    10                     return nums[i];
    11                 }
    12                 // 把当前元素放到正确的位置
    13                 int temp = nums[nums[i]];
    14                 nums[nums[i]] = nums[i];
    15                 nums[i] = temp;
    16             }
    17         }
    18         return -1;
    19     }
    20 }

    leetcode运行时间为1ms, 空间为46.3MB

    复杂度分析:

    时间复杂度:最多完整的遍历一次数组,平均复杂度为O(n/2)

    空间复杂度:O(1)

    解法三:利用HashSet

    判断当前元素是否存在于HashSet,如果存在说明是重复元素,直接返回,否则把这个元素存入HashSet

     1 class Solution {
     2     public int findRepeatNumber(int[] nums) {
     3         int len = nums.length;
     4 
     5         HashSet<Integer> hs = new HashSet<Integer>();
     6         for(int num : nums){
     7             if(hs.contains(num)){
     8                 return num;
     9             }
    10             hs.add(num);
    11         }
    12         return -1;
    13     }
    14 }

    leetcode运行时间为10ms, 空间为47.6MB, 可以看到这个运行时间远大于上面两种方法,所以知道对HastSet虽然也是以hash函数来存取元素的,但是效率远低于直接操作数组。

    复杂度分析:

    时间复杂度:最多完整的遍历一次数组,平均复杂度为O(n/2)

    空间复杂度:hashset中存储的元素个数,O(n)

  • 相关阅读:
    数据类型之间的转换
    博客园页面美化全系列
    drf——django的缓存和信号
    PEP8规范
    drf——drf局部使用,全局使用顺序
    drf—— xadmin的使用
    drf—— Book系列连表接口
    drf—— base64加码与解码
    drf——小知识
    drf—— 响聊聊cookie session token的演变
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13751247.html
Copyright © 2011-2022 走看看