题目正文:

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 }
Point

相关文章: