leetcode笔记之[961. 在长度 2N 的数组中找出重复 N 次的元素]

69 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

题目描述

961. 在长度 2N 的数组中找出重复 N 次的元素

给你一个整数数组 nums ,该数组具有以下属性:

  • nums.length == 2 * n.
  • nums 包含 n + 1 个 不同的 元素
  • nums 中恰有一个元素重复 n 次

找出并返回重复了 n 次的那个元素。

 

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [5,1,5,2,5,3,5,4]
输出:5

提示:

  • 2 <= n <= 5000
  • nums.length == 2 * n
  • 0 <= nums[i] <= 10^4
  • nums 由 n + 1 个 不同的 元素组成,且其中一个元素恰好重复 n 次

思路分析

这题最容易想到两种方法。其中一种是排序,然后再比较所有相邻两个数,时间复杂度O(nlgn)。另一种是用哈希存每个数字出现次数,时间复杂度O(n),但空间复杂度也是O(n)。

考虑划分子问题,那么任意取一个子数组,不知道这一个子数组有没有以及会有多少个重复的数在,没法直接分治。

想再优化还是要从问题的状态转换方式着手,每看一个数,这个数都有两种可能,是出现n次的或者只出现1次。一个在2n个元素里面出现n次的元素应该有什么特别的性质才对。结合数组是一段连续的长度2n的空间的性质(类似线段),可以发现n次出现的元素在空间距离上应该有约束。

假设n个重复元素中,相邻两个元素中间都存在2个其他元素,那么数组总长是3n-2。除了n=2时,其他情况下3n-2>2n,因此可以知道一定存在某两个重复元素,它们中间最多一个元素。每个数组中,所有重复元素对之间的的距离最小值只能为0或1。

我们只要比较原数组所有nums[i]和nums[i+1],所有nums[i]和nums[i+2],找到相等的一对元素,返回该元素即可。

AC 代码

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