关于leetcode:LeetCode刷题笔记数组中重复的数据

5次阅读

共计 1230 个字符,预计需要花费 4 分钟才能阅读完成。

原文:https://dushusir.com/leetcode…

问题

给你一个长度为 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 中的每个元素呈现 一次 两次

解法一

思路:

利用 Set 值惟一的个性,一直向一个空的 Set 外面增加 nums 中的数字,再应用 set.add办法,通过获取 set 长度是否减少来判断是否有反复数字呈现。

代码:

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findDuplicates = function(nums) {const set = new Set() // 惟一值测验
    const result = [] // 后果数组

    nums.forEach(n => {
        const preSize = set.size

        // 应用 set.add 办法,通过获取 set 长度是否减少来判断是否有反复数字呈现
        set.add(n)

        // 发现反复数字
        if(preSize === set.size){result.push(n)
        }
    })

    return result
};

解法二

思路:

遍历整个数组,将每一个数字视为数组地位信息,再将每一个地位对应的数字反转为正数,相当于做一个标识,表明这个数字对应的地位,曾经有数字占用了,下一次再遇到这个数字如果发现是正数就表明曾经呈现过。

比方 [4,3,2,7,8,2,3,1],走到第一个 2 的时候,翻转地位为 1 的数字 3-3,走到下一个 2 的时候,就能发现地位为 1 的数字为 -3,曾经被翻转过了,表明数字 2 呈现了两次。

代码:

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findDuplicates = function(nums) {let result = [];
    for (let i = 0; i < nums.length; i++) {let num = Math.abs(nums[i]);
        if (nums[num - 1] > 0) {
            /**
             把数字翻转为正数的目标是,做一个标识,表明这个数字对应的地位,曾经有数字占用了,下一次再遇到这个数字如果发现是正数就表明曾经呈现过

             比方[4,3,2,7,8,2,3,1]

             走到第一个 2 的时候,地位为 1 的数字为 3,将 3 翻转为 -3,走到下一个 2 的时候,翻转 3 的时候发现曾经被翻转过了
             */
            nums[num - 1] *= -1;
        } else {result.push(num);
        }
    }
    return result;

};

参考

  • LeetCode 笔记:数组中反复的数据
  • 442. 数组中反复的数据
正文完
 0