Skip to content

Latest commit

 

History

History
133 lines (95 loc) · 4.14 KB

1346.md

File metadata and controls

133 lines (95 loc) · 4.14 KB

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

Hi 大家好,我是张小猪。欢迎来到『宝宝也能看懂』系列之 leetcode 周赛题解。

这里是第 175 期的第 1 题,也是题目列表中的第 1346 题 -- 『检查整数及其两倍数是否存在』

题目描述

给你一个整数数组 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

官方难度

EASY

解决思路

题目的描述比较正式,如果简单的说其实就是,给定了一个数组,需要确认其中是否有一个数是另一个数的两倍。

相信一直看小猪题解的小伙伴们读完这道题就会有思路啦,毕竟也是 EASY 难度,小猪也就不做过多的分析啦。唯一需要提到的一点就是,我们是需要寻找到另一个数而不是当前数,即如果数组中只存在一个 0,那么是不能返回 true 的。并且,如果 xy 的两倍,那么 y 必然是 x 的一半。这句话看起来是废话,不过它背后的意思是,我们在遍历的过程中,只需要进行单方向的检查即可,不用对左右两个方向都检查了。

下面给出两种常见方案:

  • 暴力搜索,针对每个数字在数组中去寻找目标数字。
  • 存储历史数值,以供后续数字直接查找到。

直接方案

暴力搜索没有过多可以说的内容,只需要注意到上面分析中提到的两个问题即可。具体流程如下:

  1. 遍历数组。
  2. 对于每一个值,遍历它后面的值,看看是否存在它的一半或者两倍。
  3. 返回结果。

基于这个流程,我们可以实现类似下面的代码:

const checkIfExist = arr => {
  for (let i = 0; i < arr.length; ++i) {
    for (let j = i + 1; j < arr.length; ++j) {
      if (arr[j] === arr[i] << 1 || arr[j] === arr[i] / 2) return true;
    }
  }
  return false;
};

换个思路

对于存储历史值的方案,我们需要用到额外的空间来记录。这里我们可以用定长数组,也可以用集合。具体流程如下:

  1. 遍历数组。
  2. 记录出现过的值。
  3. 判断出现过的值是否有当前值的一半或者两倍。
  4. 返回结果。

基于这个流程,小猪这里把两种储存方式的代码都写了出来,供小伙伴们参考:

// 基于定长 Uint8Array 记录
const checkIfExist = arr => {
  const neg = new Uint8Array(1000);
  const pos = new Uint8Array(1000);
  for (const val of arr) {
    const arr = val > 0 ? pos : neg;
    const v2 = Math.abs(val);
    if (arr[v2 << 1] === 1 || arr[v2 / 2]) return true;
    arr[v2] = 1;
  }
  return false;
};
// 基于 Set 记录
const checkIfExist = arr => {
  const set = new Set();
  for (const val of arr) {
    if (set.has(val << 1) || set.has(val / 2)) return true;
    set.add(val);
  }
  return false;
};

总结

周赛第一题惯例送分。其实这个问题在比较初级的面试中小猪也用过,其中直接的暴力搜索方案是很容易被面试者提到,可是能提到 O(n) 的优化方案却不到一半。

小猪也不清楚具体的原因,所以这里专门把两种方案都写了出来。希望能帮到还不太清楚的小伙伴,小猪爱你们哟~

相关链接

我的微信公众号:张小猪粉鼻子