一. 缘来缘起
拳不离手,曲不离口。周末了,来活跃一下思路,保持对代码的敏感。我们来看一道有趣的腾讯笔试题目:
在平面内,随意给定4个点,如何判断他们能否组成一个正方形(为简便起见,假设这些点的坐标都是整数)。
这个问题,任何初中毕业的学生,基本都能看懂题目,且很容易想出如下4种判定方法:
-
矩形 + 邻边相等
-
矩形 + 对角线垂直
-
菱形 + 邻边垂直
-
菱形 + 对角线相等
二. 编程实现
思考一下,究竟采用哪种判定方式呢?由于4个点的顺序不固定,所以很难确定什么叫"邻边"和"垂直",所以,选择的方式是:
菱形 + 对角线相等
那么,有的朋友会说,4个点的顺序无法确定,对角线也无法确定啊。其实不然,我们可以求出最长的2条,把它们看作对角线。
接下来,思路就清晰了:4个点,形成6条线段,把最长的2条看作对角线,把剩余的4条看成边,然后,仅依赖长度关系就可以了。
所以,算法是:4条短线段相等(菱形),2条长线段相等,必定是正方形,问题完美解决了。我们来看看代码的实现和leetcode自测。
import "sort"
func validSquare(p1 []int, p2 []int, p3 []int, p4 []int) bool {
var a []int
a = append(a, distanceSqare(p1, p2))
a = append(a, distanceSqare(p1, p3))
a = append(a, distanceSqare(p1, p4))
a = append(a, distanceSqare(p2, p3))
a = append(a, distanceSqare(p2, p4))
a = append(a, distanceSqare(p3, p4))
sort.Ints(a)
if a[0] == a[1] && a[1] == a[2] && a[2] == a[3] && a[4] == a[5] && a[0] > 0 && a[0] < a[4] {
return true
}
return false
}
func square(x int) int {
return x * x
}
func distanceSqare(p []int, q []int) int {
return square(p[0] - q[0]) + square(p[1] - q[1])
}
在leetcode上进行了测试,OK.
三. 最后的话
腾讯的这道笔试题目,看似简单,但要在短时间内想出合理的优雅解法,也不太容易。
笔试面试中,遇到难题后,不要慌,相信自己的逻辑分析和判断,没什么大不了的。
祝大家笔试面试顺利,拿到更好offer,钱多多,福利多多,也欢迎大家一起刷起来。