前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#刷遍Leetcode面试题系列连载(5):No.593 - 有效的正方形

C#刷遍Leetcode面试题系列连载(5):No.593 - 有效的正方形

作者头像
Enjoy233
发布2019-10-30 11:58:48
2660
发布2019-10-30 11:58:48
举报

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/yanglr2010/article/details/102792182

上一篇 LeetCode 面试题中,我们分析了一道难度为 Easy 的数学题 - 自除数,提供了两种方法。今天我们来分析一道难度为 Medium 的面试题。

img
img

今天要给大家分析的面试题是 LeetCode 上第 593 号问题,

LeetCode - 593. 有效的正方形

https://leetcode-cn.com/problems/valid-square

题目描述

给定二维空间中四点的坐标,返回四点是否可以构造一个正方形。

一个点的坐标(x,y)由一个有两个整数的整数数组表示。

示例:

代码语言:javascript
复制
输入: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
输出: True

注意:

  1. 所有输入整数都在 [-10000,10000] 范围内。
  2. 一个有效的正方形有四个等长的正长和四个等角(90度角)。
  3. 输入点没有顺序。

解题思路:

可以基于正方形的特征来判断~

方法1: 由于点是以坐标形式给出的,于是可以围绕向量垂直以及对角线长度的平方为边长平方的 2 倍来做.

而向量垂直地判定依据是向量点乘的乘积为0)。

方法2: 判断两组平行边长度相等,对角线长度相等,且至少一对邻边长度相等. (有下图两种情形,p1、p2两个点相邻或不相邻)

dotNET匠人 - 示意图
dotNET匠人 - 示意图

临界情况: 4个输入的点中有两个或多个相同,直接返回false。

方法1 已AC代码:

代码语言:javascript
复制
public class Solution
{
    public bool ValidSquare(int[] p1, int[] p2, int[] p3, int[] p4)
    {
        int[] vect1 = { p2[0] - p1[0], p2[1] - p1[1] };
        int[] vect2 = { p4[0] - p1[0], p4[1] - p1[1] };
        int[] vect3 = { p3[0] - p1[0], p3[1] - p1[1] };
        List<int[]> vects = new List<int[]> { vect1, vect2, vect3 };

        if (vects.Any(x => x.SequenceEqual(new[]{0, 0}))) // 输入的点中存在相同的, 即有(0, 0)的向量
            return false;

        List<int> lenSquaresFromP1 = new List<int> { GetLenSquare(p2, p1), GetLenSquare(p4, p1), GetLenSquare(p3, p1) };
        List<int> extraLenSquares = new List<int> { GetLenSquare(p2, p3), GetLenSquare(p2, p4), GetLenSquare(p3, p4) };

        if (lenSquaresFromP1.Max() != extraLenSquares.Max())
            return false; // 当从p1出发的最长距离不为所有点两两之间距离的最大值时,只是菱形,不是正方形

        var maxLenSquare = lenSquaresFromP1.Max(); // 后面要remove, 此处作备份
        int maxPos = lenSquaresFromP1.IndexOf(maxLenSquare);
        lenSquaresFromP1.RemoveAt(maxPos);
        vects.RemoveAt(maxPos);

        if (lenSquaresFromP1[0] == lenSquaresFromP1[1] && lenSquaresFromP1[0] * 2 == maxLenSquare &&
            VectorCross(vects[0], vects[1]) == 0)
            return true;

        return false;
    }

    private int VectorCross(int[] vect1, int[] vect2) => vect1[0] * vect2[0] +
                                                         vect1[1] * vect2[1];

    private int GetLenSquare(int[] point1, int[] point2) => (point2[0] - point1[0]) * (point2[0] - point1[0]) +
                                                         (point2[1] - point1[1]) * (point2[1] - point1[1]);
}

执行用时: 104 ms, 在所有 csharp 提交中击败了80.00%的用户.

方法2 已AC代码:

代码语言:javascript
复制
public class Solution
{
    public bool ValidSquare(int[] p1, int[] p2, int[] p3, int[] p4)
    {
        if (GetLenSquare(p1, p2) == 0 || GetLenSquare(p2, p3) == 0 || GetLenSquare(p3, p4) == 0 || GetLenSquare(p1, p4) == 0)
            return false;

        return GetLenSquare(p1, p2) == GetLenSquare(p3, p4) && GetLenSquare(p1, p3) == GetLenSquare(p2, p4) && GetLenSquare(p1, p4) == GetLenSquare(p2, p3) &&
               (GetLenSquare(p1, p2) == GetLenSquare(p1, p3) || GetLenSquare(p1, p2) == GetLenSquare(p1, p4) || GetLenSquare(p1, p3) == GetLenSquare(p1, p4));
    }

    private int GetLenSquare(int[] point1, int[] point2) => (point2[0] - point1[0]) * (point2[0] - point1[0]) +
                                                         (point2[1] - point1[1]) * (point2[1] - point1[1]);
}

执行用时: 108 ms, 在所有 csharp 提交中击败了80.00%的用户.

欢迎提出更佳的解决思路~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 解题思路:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档