检查整数及其两倍数是否存在

标签: 数组 哈希表 双指针 二分查找 排序

难度: Easy

给你一个整数数组 arr,请你检查是否存在两个整数 NM,满足 N 是 M 的两倍(即,N = 2 * M)。

更正式地,检查是否存在两个下标 ij 满足:

  • i != j
  • 0 <= i, j < arr.length
  • arr[i] == 2 * arr[j]

示例 1:

输入:arr = [10,2,5,3]
输出:true
解释:N = 10 是 M = 5 的两倍,即 10 = 2 * 5 。

示例 2:

输入:arr = [7,1,14,11]
输出:true
解释:N = 14 是 M = 7 的两倍,即 14 = 2 * 7 

示例 3:

输入:arr = [3,1,7,11]
输出:false
解释:在该情况下不存在 N 和 M 满足 N = 2 * M 。

提示:

  • 2 <= arr.length <= 500
  • -10^3 <= arr[i] <= 10^3

Submission

运行时间: 24 ms

内存: 16.6 MB

class Solution:
    def checkIfExist(self, arr: List[int]) -> bool:
        s = set(arr)
        count = 0
        for i in range(len(arr)):
            if arr[i] == 0:
                if count == 1:
                    return True
                count += 1
            else:
                if arr[i] * 2 in s:
                    return True
        return False

Explain

这个解法利用一个集合来记录数组中的所有元素,以实现快速查找。首先,将数组中的所有元素添加到集合中。然后遍历数组,对于每个元素,如果是0,检查是否已经遇到过0(因为0的两倍还是0),如果是,则返回true。对于非0元素,检查集合中是否存在其两倍的数,如果存在,则返回true。如果整个数组遍历完成后都没有找到符合条件的元素对,最后返回false。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def checkIfExist(self, arr: List[int]) -> bool:
        s = set(arr)  # 创建一个集合包含数组所有元素
        count = 0  # 用于统计0的数量
        for i in range(len(arr)):
            if arr[i] == 0:
                if count == 1:  # 如果之前已经有一个0,那么找到了符合条件的对
                    return True
                count += 1  # 统计0的数量
            else:
                if arr[i] * 2 in s:  # 检查当前元素的两倍是否存在于集合中
                    return True
        return False  # 如果没有找到符合条件的元素对,返回false

Explore

在处理0的情况时,只有在第二次遇到0才返回true,是因为0的两倍还是0。如果数组中只有一个0,那么它没有另一个0与之配对,因此不满足题目的条件。只有当至少有两个0时,这两个0才能形成有效的 '整数及其两倍数' 对。在集合中查找0的两倍并没有特殊的处理逻辑,但需要确保集合中至少有两个0才可以返回true。

将数组中的所有元素一次性加入集合并不影响判断当前元素的两倍是否已经在集合中存在。这种方法可以保证在检查某个元素时,集合中已经包含所有数组元素,从而可以快速判断任何元素的两倍数是否存在于集合中。这种处理方式简化了逻辑并优化了查找速度。

是的,这种方法仍然有效,即使数组中存在负数。对于负数,两倍关系仍然成立,例如,-4确实是-2的两倍。因为集合中包含了所有元素,所以无论是正数还是负数,只要存在某个数的两倍数,无论其正负,都可以通过在集合中查找来正确识别。

在这种算法实现中,元素的顺序不会影响检查结果。因为在开始遍历前,所有数组元素都已经被添加到集合中,这意味着无论何时遍历到某个元素,集合里已经包含了所有其他的元素。因此,无论是先遇到大数还是小数,只要集合中存在某个数的两倍,都可以立即检测到。这确保了算法的正确性不受元素顺序的影响。