分割数组

标签: 数组 哈希表 计数

难度: Easy

给你一个长度为 偶数 的整数数组 nums 。你需要将这个数组分割成 nums1nums2 两部分,要求:

  • nums1.length == nums2.length == nums.length / 2
  • nums1 应包含 互不相同 的元素。
  • nums2也应包含 互不相同 的元素。

如果能够分割数组就返回 true ,否则返回 false

示例 1:

输入:nums = [1,1,2,2,3,4]
输出:true
解释:分割 nums 的可行方案之一是 nums1 = [1,2,3] 和 nums2 = [1,2,4] 。

示例 2:

输入:nums = [1,1,1,1]
输出:false
解释:分割 nums 的唯一可行方案是 nums1 = [1,1] 和 nums2 = [1,1] 。但 nums1 和 nums2 都不是由互不相同的元素构成。因此,返回 false 。

提示:

  • 1 <= nums.length <= 100
  • nums.length % 2 == 0
  • 1 <= nums[i] <= 100

Submission

运行时间: 17 ms

内存: 16.0 MB

class Solution:
    def isPossibleToSplit(self, nums: List[int]) -> bool:
        d = defaultdict(int)
        for num in nums:
            d[num] += 1
            if d[num] > 2:
                return False
        return True

Explain

该题解采用哈希表来记录数组中每个元素的出现次数。首先,遍历整个数组,将每个元素的出现次数记录到哈希表中。在遍历的过程中,如果发现数组中的任何一个元素出现的次数超过2次,则无法将数组分割成两个包含互不相同元素的子数组,因此直接返回False。如果整个数组遍历完成后,没有发现任何元素出现次数超过2次,则返回True,表示可以分割数组。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def isPossibleToSplit(self, nums: List[int]) -> bool:
        d = defaultdict(int)  # 创建一个默认值为int的哈希表
        for num in nums:  # 遍历数组中的每个元素
            d[num] += 1  # 将元素的出现次数加一
            if d[num] > 2:  # 如果任何元素出现超过两次
                return False  # 返回False,因为无法分割
        return True  # 如果没有元素出现超过两次,返回True

Explore

在这个问题中,数组需要被分割成两个长度相等的子数组,且每个子数组中的元素都必须是唯一的。如果数组中的某个元素出现超过两次,例如三次或更多,那么无论如何分割,至少有一个子数组将必须包含至少两个相同的元素,因此无法满足题目要求每个子数组元素互不相同的条件。因此,一旦检测到任何元素出现超过两次,就可以立即确定无法按照要求分割数组,返回False。

题解的方法确实考虑了保证两个子数组都包含互不相同元素的主要条件,即确保没有任何元素出现次数超过两次。因为数组长度是偶数,且要求分割成两个等长的子数组,如果每个元素最多出现两次,就可以将每个元素的两次出现分别放入两个子数组中。这样,每个子数组都能满足元素互不相同的条件。在这种情况下,没有其他额外的条件需要考虑。

使用哈希表来统计元素的频率是解决这类问题的一种非常高效和常见的方法。哈希表的主要优势在于能够提供快速的插入、查找和更新操作,这些操作的平均时间复杂度为O(1),非常适合频率统计的需求。尽管可以考虑使用其他数据结构如排序数组或树结构(如二叉搜索树、AVL树等)来统计频率,但这些方法在插入和查找操作上通常有更高的时间复杂度(O(log n)),并不提供比哈希表更明显的优势。因此,对于本问题,使用哈希表是一个非常合理且效率高的选择。