|
| 1 | +package com.stevesun.solutions; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Arrays; |
| 5 | +import java.util.List; |
| 6 | + |
| 7 | +/** |
| 8 | + * 593. Valid Square |
| 9 | + * |
| 10 | + * Given the coordinates of four points in 2D space, return whether the four points could construct a square. |
| 11 | +
|
| 12 | + The coordinate (x,y) of a point is represented by an integer array with two integers. |
| 13 | +
|
| 14 | + Example: |
| 15 | + Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1] |
| 16 | + Output: True |
| 17 | + Note: |
| 18 | + All the input integers are in the range [-10000, 10000]. |
| 19 | + A valid square has four equal sides with positive length and four equal angles (90-degree angles). |
| 20 | + Input points have no order. |
| 21 | +
|
| 22 | + */ |
| 23 | +public class _593 { |
| 24 | + /**Note: I don't need to use backtracking to find all permutations, this is an overkill. |
| 25 | + * This is the most easy one: https://leetcode.com/articles/kill-process-2/#approach-3-checking-every-case-accepted*/ |
| 26 | + |
| 27 | + |
| 28 | + public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) { |
| 29 | + List<int[]> input = new ArrayList<>(Arrays.asList(p1, p2, p3, p4)); |
| 30 | + List<List<int[]>> allPermuations = getAllPermutations(input); |
| 31 | + for (List<int[]> eachPermutation : allPermuations) { |
| 32 | + if (isValid(eachPermutation)) return true; |
| 33 | + } |
| 34 | + return false; |
| 35 | + } |
| 36 | + |
| 37 | + private List<List<int[]>> getAllPermutations(List<int[]> input) { |
| 38 | + List<List<int[]>> result = new ArrayList(); |
| 39 | + List<int[]> init = new ArrayList<>(); |
| 40 | + result.add(init); |
| 41 | + return backTracking(result, input, 0); |
| 42 | + } |
| 43 | + |
| 44 | + private List<List<int[]>> backTracking(List<List<int[]>> result, List<int[]> input, int pos) { |
| 45 | + if (pos == input.size()) { |
| 46 | + return result; |
| 47 | + } |
| 48 | + List<List<int[]>> newResult = new ArrayList<>(); |
| 49 | + for (List<int[]> eachList : result) { |
| 50 | + for (int i = 0; i <= eachList.size(); i++) { |
| 51 | + List<int[]> newList = new ArrayList<>(eachList); |
| 52 | + newList.add(i, input.get(pos)); |
| 53 | + newResult.add(newList); |
| 54 | + } |
| 55 | + } |
| 56 | + result = newResult; |
| 57 | + return backTracking(result, input, pos+1); |
| 58 | + } |
| 59 | + |
| 60 | + private boolean isValid(List<int[]> points) { |
| 61 | + int[] p1 = points.get(0); |
| 62 | + int[] p2 = points.get(1); |
| 63 | + int[] p3 = points.get(2); |
| 64 | + int[] p4 = points.get(3); |
| 65 | + double distance = (Math.pow(p1[0]-p2[0], 2) + Math.pow(p1[1] - p2[1], 2)); |
| 66 | + return distance == (Math.pow(p2[0]-p3[0], 2) + Math.pow(p2[1] - p3[1], 2)) |
| 67 | + && distance == (Math.pow(p3[0]-p4[0], 2) + Math.pow(p3[1] - p4[1], 2)) |
| 68 | + && distance == (Math.pow(p4[0]-p1[0], 2) + Math.pow(p4[1] - p1[1], 2)) |
| 69 | + && isRightAngle(p1, p2, p3) |
| 70 | + && noDuplicate(p1, p2, p3, p4); |
| 71 | + } |
| 72 | + |
| 73 | + public boolean noDuplicate(int[] p1, int[] p2, int[] p3, int[] p4) { |
| 74 | + return !Arrays.equals(p1, p2) |
| 75 | + && !Arrays.equals(p1, p3) |
| 76 | + && !Arrays.equals(p1, p4) |
| 77 | + && !Arrays.equals(p2, p3) |
| 78 | + && !Arrays.equals(p2, p4) |
| 79 | + && !Arrays.equals(p3, p4); |
| 80 | + } |
| 81 | + |
| 82 | + public boolean isRightAngle(int[] p1, int[] p2, int[] p3) { |
| 83 | + double angle1 = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]); |
| 84 | + double angle2 = Math.atan2(p3[1] - p1[1], p3[0] - p1[0]); |
| 85 | + double degree = Math.toDegrees(angle1-angle2); |
| 86 | + return degree%45 == 0; |
| 87 | + } |
| 88 | + |
| 89 | +} |
0 commit comments