题目正文:
http://coursera.cs.princeton.edu/algs4/assignments/collinear.html
作业难点:
1、仔细思考会感觉有很多实现方法,但是如果没有适当使用排序,算法时间复杂度就会轻易超过要求。(包括暴力算法)
2、隐含需要实现自己的数据结构用来组织“线”的集合,当然也可以用Stack或者Queue或者LinkedList,但是我个人是自己实现的。
3、由于一条线段只能出现一次,所以有一个去重的问题。(最难)
作业技巧:
1、基本按照题目的先后顺序实现,结合视频学习中的一些知识点就可以把任务串起来,不会无从下手。
2、SlopTo的计算结果和点数组的排列顺序有关吗?A.SlopeTo(B)和B.SlopeTo(A)其实是一样的,合理利用cache防止多次计算。
3、在暴力方法中,引入排序可以解决去重问题。
4、如果去重是通过在结果集合中查找是否存在,就铁定会超过复杂度要求,所以必须在添加结果集之前就能判断。
这里就有一个重要推论:a-b-c-d线段,无论从a开始查找还是从b开始查找,线段最大和最小点都不变为a和d,所以我们只需要找到起始点为线段最小点的线段就可以了,其他线段均抛弃即可
代码参考:
(这是我自己亲测100分的答案,不代表写得最好,请在自己实在完成不了的时候再看,不然的话做这个题目的意义一点都没有)
1 import edu.princeton.cs.algs4.StdDraw; 2 3 /****************************************************************************** 4 * Compilation: javac Point.java 5 * Execution: java Point 6 * Dependencies: none 7 * 8 * An immutable data type for points in the plane. 9 * For use on Coursera, Algorithms Part I programming assignment. 10 * 11 ******************************************************************************/ 12 import java.util.Comparator; 13 14 15 public class Point implements Comparable<Point> { 16 private final int x; // x-coordinate of this point 17 private final int y; // y-coordinate of this point 18 19 /** 20 * Initializes a new point. 21 * 22 * @param x the <em>x</em>-coordinate of the point 23 * @param y the <em>y</em>-coordinate of the point 24 */ 25 public Point(int x, int y) { 26 /* DO NOT MODIFY */ 27 this.x = x; 28 this.y = y; 29 } 30 31 /** 32 * Draws this point to standard draw. 33 */ 34 public void draw() { 35 /* DO NOT MODIFY */ 36 StdDraw.point(x, y); 37 } 38 39 /** 40 * Draws the line segment between this point and the specified point 41 * to standard draw. 42 * 43 * @param that the other point 44 */ 45 public void drawTo(Point that) { 46 /* DO NOT MODIFY */ 47 StdDraw.line(this.x, this.y, that.x, that.y); 48 } 49 50 /** 51 * Returns the slope between this point and the specified point. 52 * Formally, if the two points are (x0, y0) and (x1, y1), then the slope 53 * is (y1 - y0) / (x1 - x0). For completeness, the slope is defined to be 54 * +0.0 if the line segment connecting the two points is horizontal; 55 * Double.POSITIVE_INFINITY if the line segment is vertical; 56 * and Double.NEGATIVE_INFINITY if (x0, y0) and (x1, y1) are equal. 57 * 58 * @param that the other point 59 * @return the slope between this point and the specified point 60 */ 61 public double slopeTo(Point that) { 62 if ((this.x == that.x) && (this.y == that.y)) { 63 return Double.NEGATIVE_INFINITY; 64 } else if (this.x == that.x) { 65 return Double.POSITIVE_INFINITY; 66 } else if (this.y == that.y) { 67 return 0; 68 } else { 69 return (that.y - this.y) / (double) (that.x - this.x); 70 } 71 } 72 73 /** 74 * Compares two points by y-coordinate, breaking ties by x-coordinate. 75 * Formally, the invoking point (x0, y0) is less than the argument point 76 * (x1, y1) if and only if either y0 < y1 or if y0 = y1 and x0 < x1. 77 * 78 * @param that the other point 79 * @return the value <tt>0</tt> if this point is equal to the argument 80 * point (x0 = x1 and y0 = y1); 81 * a negative integer if this point is less than the argument 82 * point; and a positive integer if this point is greater than the 83 * argument point 84 */ 85 public int compareTo(Point that) { 86 if ((this.x == that.x) && (this.y == that.y)) { 87 return 0; 88 } else if ((that.y > this.y) || 89 ((that.y == this.y) && (that.x > this.x))) { 90 return -1; 91 } else { 92 return 1; 93 } 94 } 95 96 /** 97 * Compares two points by the slope they make with this point. 98 * The slope is defined as in the slopeTo() method. 99 * 100 * @return the Comparator that defines this ordering on points 101 */ 102 public Comparator<Point> slopeOrder() { 103 return new SlopeOrder(this); 104 } 105 106 /** 107 * Returns a string representation of this point. 108 * This method is provide for debugging; 109 * your program should not rely on the format of the string representation. 110 * 111 * @return a string representation of this point 112 */ 113 public String toString() { 114 /* DO NOT MODIFY */ 115 return "(" + x + ", " + y + ")"; 116 } 117 118 /** 119 * Unit tests the Point data type. 120 */ 121 public static void main(String[] args) { 122 /* YOUR CODE HERE */ 123 } 124 125 private class SlopeOrder implements Comparator<Point> { 126 private Point p0; 127 128 public SlopeOrder(Point invokePoint) { 129 p0 = invokePoint; 130 } 131 132 public int compare(Point p1, Point p2) { 133 double d01 = p0.slopeTo(p1); 134 double d02 = p0.slopeTo(p2); 135 136 if (d01 < d02) { 137 return -1; 138 } else if (d01 > d02) { 139 return 1; 140 } else { 141 return 0; 142 } 143 } 144 } 145 }