1.找出数组中的重复数字

记录一下做leetcode上算法题的过程,并且摘录一些其他比较好的想法和解法。

题:

找出数组中重复的数字。


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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
 

我的解法:(C++)

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        set<int> _temp;
        for(auto aa : nums)
        {
            auto _result = _temp.insert(aa);
            if(!_result.second)
                return aa;
        }

        return 0;
    }
};

不太熟悉stl。

时间复杂度比较高一点,并且借助了额外空间.

解法摘录:

扫描二维码关注公众号,回复: 9536872 查看本文章

方法一:哈希表(最自然,但是要额外空间)
一个实作:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int hash[100000]={0};
        for(int i=0;i<=nums.size()-1;i++){
            hash[nums[i]]++;
        }
        for(int i=0;i<=100000;i++){
            if(hash[i]>1) return i;
        }
        return 0;
    }
};

作者:xiao-jie-chou-zhi-yan-2
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/c-by-xiao-jie-chou-zhi-yan-2/

分析:这种方法不修改原始数组,但是使用了 O(N)的 空间,使用空间换时间,是最正常的思路,时间复杂度是 O(N)。

方法二:先排序再比较

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int res;

        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size()-2;i++){
            if (nums[i] == nums[i+1]){
                res = nums[i];
                break;
            }
        }
    return res;    
    }
};

作者:xu-zhou-geng
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/cji-yu-pai-xu-by-xu-zhou-geng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法三:桶思想+抽屉原理

  • 由于数组元素的值都在指定的范围内,这个范围恰恰好与数组的下标可以一一对应;
  • 因此看到数值,就可以知道它应该放在什么位置,这里 nums[i] 应该放在下标为 i 的位置上,就根据这一点解题,这种思想与桶排序、哈希表的思想是一致的
import java.util.Arrays;

public class Solution {

    public int findRepeatNumber(int[] nums) {
        int len = nums.length;

        for (int i = 0; i < len; i++) {
            // 如果当前的数 nums[i] 没有在下标为 i 的位置上,就把它交换到下标 i 上
            // 交换过来的数还得做相同的操作,因此这里使用 while
            // 可以在此处将数组输出打印,观察程序运行流程
            // System.out.println(Arrays.toString(nums));

            while (nums[i] != i) {

                if (nums[i] == nums[nums[i]]) {
                    // 如果下标为 nums[i] 的数值 nums[nums[i]] 它们二者相等
                    // 正好找到了重复的元素,将它返回
                    return nums[i];
                }
                swap(nums, i, nums[i]);
            }
        }
        throw new IllegalArgumentException("数组中不存在重复数字!");
    }

    private void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }

}

作者:liweiwei1419
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/tong-de-si-xiang-by-liweiwei1419/
来源:力扣(LeetCode)

方法四:二分法

方法五:借助额外数组,布尔数组判重

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        bool flag[nums.size()];
        memset(flag,false,sizeof(flag));
        for(int i=0;i<nums.size();i++)
        if(flag[nums[i]])
        return nums[i];
        else
        flag[nums[i]]=true;
        return -1;
    }
};

作者:lhh2001-2
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/bu-er-shu-zu-pan-zhong-by-lhh2001-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
发布了35 篇原创文章 · 获赞 5 · 访问量 401

猜你喜欢

转载自blog.csdn.net/qq_33776188/article/details/104512884
今日推荐