LeetCode - 447 - 回旋镖的数量(number-of-boomerangs)

Create by jsliang on 2019-07-29 19:45:232019-7-29 22:42:06

一 目录

不折腾的前端,和咸鱼有什么区别

| 目录 | | --- | | 一 目录 | | 二 前言 | | 三 解题 | | 四 执行测试 | | 五 LeetCode Submit | | 六 解题思路 |

二 前言

  • 难度:简单

  • 涉及知识:哈希表

  • 题目地址:https://leetcode-cn.com/problems/number-of-boomerangs/

  • 题目内容

给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。	
找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。	
示例:	
输入:	
[[0,0],[1,0],[2,0]]	
输出:	
2	
解释:	
两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]

三 解题

小伙伴可以先自己在本地尝试解题,再回来看看 jsliang 的解题思路。

  • 解题代码

const dist = (i, j) => {	
  return (i[0] - j[0]) * (i[0] - j[0]) + (i[1] - j[1]) * (i[1] - j[1]);	
};	
const judge = (i, j, k) => {	
  let count = 0;	
  if (dist(i, j) == dist(i, k)) {	
    count += 2;	
  }	
  if (dist(j, i) == dist(j, k)) {	
    count += 2;	
  }	
  if (dist(k, i) == dist(k, j)) {	
    count += 2;	
  }	
  return count;	
};	
const numberOfBoomerangs = (points) => {	
  let result = 0;	
  for (let i = 0; i < points.length - 2; i++) {	
    for (let j = i + 1; j < points.length - 1; j++) {	
      for (let k = j + 1; k < points.length; k++) {	
        result += judge(points[i], points[j], points[k]);	
      }	
    }	
  }	
  return result;	
};

四 执行测试

  1. point: [[0,0],[1,0],[2,0]]

  2. return

2

五 LeetCode Submit

√ Accepted	
  √ 31/31 cases passed (2048 ms)	
  √ Your runtime beats 27.69 % of javascript submissions	
  √ Your memory usage beats 93.75 % of javascript submissions (35 MB)

六 解题思路

目测第一眼,LeetCode 又丧心病狂啦!!!

首先,个人猜测,对于题意,个人先解析一波:

  • 回旋镖表示的为元组(i, j, k),咱不太理解,姑且认为 x,y,z 构成的三维地址。

  • i 到 j 的距离 === i 到 k 的距离。

  • [[0,0],[1,0],[2,0]] 对应的即是: [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]

由于咱没有更多的数据支持,所以我们也无法确定,是元组可以随意组成任意组,然后差值相同?

一脸蒙圈~

然后,只能求助【评论】和【题解】的大佬看看了:

Go 实现

func dist(i,j []int) int {      // 两点间的距离	
  return (i[0]-j[0])*(i[0]-j[0]) + (i[1]-j[1])*(i[1]-j[1])	
}	
func judge(i,j,k []int) int {   // 计算这三个点能构成几个“回旋镖”	
  cnt := 0	
  if dist(i,j) == dist(i,k) {	
    cnt+=2	
  }	
  if dist(j,i) == dist(j,k) {	
    cnt+=2	
  }	
  if dist(k,i) == dist(k,j) {	
    cnt+=2	
  }	
  return cnt	
}	
func numberOfBoomerangs(points [][]int) int {   // 三层循环遍历每个三元组	
  ans := 0	
  for i:=0; i<len(points)-2; i++ {	
    for j:=i+1; j<len(points)-1; j++ {	
      for k:=j+1; k<len(points); k++ {	
        ans += judge(points[i],points[j],points[k])	
      }	
    }	
  }	
  return ans	
}

说实话我也不懂 Go 语言,但是我看到了,并且我懂一点后端语言,感觉可以理解,于是尝试转换成 JavaScript:

const dist = (i, j) => {	
  return (i[0] - j[0]) * (i[0] - j[0]) + (i[1] - j[1]) * (i[1] - j[1]);	
};	
const judge = (i, j, k) => {	
  let count = 0;	
  if (dist(i, j) == dist(i, k)) {	
    count += 2;	
  }	
  if (dist(j, i) == dist(j, k)) {	
    count += 2;	
  }	
  if (dist(k, i) == dist(k, j)) {	
    count += 2;	
  }	
  return count;	
};	
const numberOfBoomerangs = (points) => {	
  let result = 0;	
  for (let i = 0; i < points.length - 2; i++) {	
    for (let j = i + 1; j < points.length - 1; j++) {	
      for (let k = j + 1; k < points.length; k++) {	
        result += judge(points[i], points[j], points[k]);	
      }	
    }	
  }	
  return result;	
};

Submit 提交:

√ Accepted	
  √ 31/31 cases passed (2048 ms)	
  √ Your runtime beats 27.69 % of javascript submissions	
  √ Your memory usage beats 93.75 % of javascript submissions (35 MB)

还真的过了,所以我们就啃下它!

接着jsliang 通过讲解上面代码,讲讲自己的理解:

1、计算两点之间的距离

const dist = (i, j) => {	
  return (i[0] - j[0]) * (i[0] - j[0]) + (i[1] - j[1]) * (i[1] - j[1]);	
};

计算两个点的距离,就是它们对应坐标的差的平方相加。

即:

  • x - [1, 2]

  • y - [2, 3]

  • dist(x, y) = (2 - 1)² + (3 - 2)²

2、计算这三个点能构成几个“回旋镖”

const judge = (i, j, k) => {	
  let count = 0;	
  if (dist(i, j) == dist(i, k)) {	
    count += 2;	
  }	
  if (dist(j, i) == dist(j, k)) {	
    count += 2;	
  }	
  if (dist(k, i) == dist(k, j)) {	
    count += 2;	
  }	
  return count;	
};

正如题目所言,i 到 j 的距离等于 i 到 k 的距离。

同样:

  • i - j === i - k

  • j - i === j - k

  • k - i === k - j

3、三层循环遍历每个三元组

const numberOfBoomerangs = (points) => {	
  let result = 0;	
  for (let i = 0; i < points.length - 2; i++) {	
    for (let j = i + 1; j < points.length - 1; j++) {	
      for (let k = j + 1; k < points.length; k++) {	
        result += judge(points[i], points[j], points[k]);	
      }	
    }	
  }	
  return result;	
};

三层遍历数组,获取到每种可能,通过 result 获取最终结果,并输出最终结果。

最后,我们解析了代码,虽然题意仍然不太清晰,但是我们可以了解到:

  1. 算法中两点距离的计算

  2. 构成一个立体物品的方法

相信后面我们会接触更多的这种题,从而逐渐明朗~

如果你有更好的理解,请留言~


不折腾的前端,和咸鱼有什么区别!

640?wx_fmt=jpeg

jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。

扫描上方二维码,关注 jsliang 的公众号,让我们一起折腾!

640?wx_fmt=png

jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值