zoukankan      html  css  js  c++  java
  • 01找出数组中重复的数

    【题目描述】

    给定一个长度为 n 的整数数组 nums,数组中所有的数字都在 0 ∼ n−1 的范围内。

    数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。

    请找出数组中任意一个重复的数字。

    注意:如果某些数字不在 0 ∼ n−1 的范围内,或数组中不包含重复数字,则返回 -1;

    样例

    给定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。
    
    返回 2 或 3。
    

    【算法描述】

    数组中的数的范围在 0 ∼ n−1是解题思路的核心。

    遍历整个数组,将数组中数放在对应的位置上即nums[i] = i,也就是说每一个数都放在了自己对应的位置上,如果有一个数x重复的话则会出现这个数与对应的数组下标不相等即x != i,并且将该数作为数组下标得到的数也为该数即num[x] == x

    整体思路如上所示,具体算法如下:

    因为数组有可能出现 0 ∼ n−1范围外的数,所以首先对数组进行遍历,如果数组中的数x < 0或者x >= n则直接返回-1;

    同样从前往后遍历数组,比如遍历到nums[i] = x时:

    • 如果x != i并且nums[x] = x则直接返回nums[i],表示已经找到重复的数

    • 如果nums[x] != x,此时需要将x放在对应的位置上,将当前位置上的数x放到以x为数组下标的位置即swap(nums[i], nums[x])。循环执行上述操作,直到将当前位置上的数放在其对应的位置上。

    执行完上述操作如果还没找到重复的数直接返回-1。

    【时间复杂度分析】

    首先会遍历一遍数组判断数组中是否有不在0~n-1范围内的数,所需时间复杂度为O(N);

    每次swap会将一个数放在正确的位置,最后一次swap会将两个数分别放在正确的位置上,n个数就有n个位置,swap操作最多执行n-1次,所以总的时间复杂度为O(N)。

    【代码示例】

    class Solution {
    public:
        int duplicateInArray(vector<int>& nums) {
            int n = nums.size();
            for (auto x : nums)
            {
                if (x < 0 || x >= n) return -1;
            }
            for (int i = 0; i < n; i++)
            {
                while (nums[nums[i]] != nums[i]) swap(nums[nums[i]], nums[i]);
                if (nums[i] != i && nums[nums[i]] == nums[i]) return nums[i];
            }
            return -1;
        }
    };
    
  • 相关阅读:
    js 基于可视区域 创建展示区域对应的经纬度二维数组
    主要看思路:区域数据去重 + JavaScript一次性展示几万条数据实例代码
    推荐js库: underscore
    开博缘由 , 可点下看看 http://www.cnblogs.com/jshare
    php--sphinx的使用
    php--validate表单验证实例
    php--validate错误信息提示样式
    php--yii框架中的ajax分页与yii框架自带的分页
    php--jquery操作全选、批量删除、加减行
    php--yii2.0框架的curl
  • 原文地址:https://www.cnblogs.com/dabric/p/15037687.html
Copyright © 2011-2022 走看看