美文网首页leetcode算法
442. 数组中重复的数据

442. 数组中重复的数据

作者: 刘翊扬 | 来源:发表于2022-05-08 11:24 被阅读0次

    442. 数组中重复的数据 - 力扣(LeetCode) (leetcode-cn.com)
    给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。

    你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。

    示例 1:

    输入:nums = [4,3,2,7,8,2,3,1]
    输出:[2,3]
    示例 2:

    输入:nums = [1,1,2]
    输出:[1]
    示例 3:

    输入:nums = [1]
    输出:[]

    提示:

    • n == nums.length
    • 1 <= n <= 105
    • 1 <= nums[i] <= n
    • nums 中的每个元素出现 一次 或 两次

    注意关键信息,1 <= nums[i] <= n ,说明数组中的元素的最大值不超过数组长度,那么我们可以根据索引,将值放入到对应的索引位置上,使其满足 i == num[i] - 1.如果不满足,则说明这些数重复了

    方法一:交换位置

    /**
         * 方法一:将元素交换到对应的位置
         *
         * @param nums
         * @return
         */
        public static List<Integer> findDuplicates(int[] nums) {
            List<Integer> ans = new ArrayList<>();
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                // 交换
                while (nums[i] != nums[nums[i] - 1]) {
                    int tmp = nums[nums[i] - 1];
                    nums[nums[i] - 1] = nums[i];
                    nums[i] = tmp;
                }
            }
            for (int i = 0; i < n; i++) {
                // 交换完成之后,还不等于,就是说明重复了
                if (i != nums[i] - 1) {
                    ans.add(nums[i]);
                }
            }
            return ans;
        }
    

    复杂度分析

    • 时间复杂度:O(n)。每一次交换操作会使得至少一个元素被交换到对应的正确位置,因此交换的次数为 O(n),总时间复杂度为 O(n)。
    • 空间复杂度:O(1)。返回值不计入空间复杂度。

    方法二:正负号

    不交换位置,我们可以将对应的数值 * -1 , 取符号,如果重复,负负得正,对应的值为正时,说明重复了

      /**
         * 方法二:使用正负号作为标记
         *
         * @param nums
         * @return
         */
        public static List<Integer> findDuplicates(int[] nums) {
            List<Integer> ans = new ArrayList<>();
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                int num = Math.abs(nums[i]);
                if (nums[num - 1] > 0) {
                    nums[num - 1] *= -1;
                } else {
                    ans.add(num);
                }
            }
            return ans;
        }
    

    复杂度分析

    • 时间复杂度:O(n)。我们只需要对数组 nums 进行一次遍历。
    • 空间复杂度:O(1)。返回值不计入空间复杂度。

    相似题目推荐:

    https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-all-duplicates-in-an-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    相关文章

      网友评论

        本文标题:442. 数组中重复的数据

        本文链接:https://www.haomeiwen.com/subject/nfqqurtx.html