Algorithm I assignment Percolation

这道题来自Algorithms 4th的公开课,是week1的assignment。该题主要是对并查集的应用,点击:参考

看过lecture后,想到解决这道题的思路并不难,不过想要拿到满分着实费功夫...累积花费了5个小时才AC。

在实现代码过程中遇到了以下问题:

  1. 时间复杂度超了,因为在实现percolates()时,采用了遍历的方式检查:所以在grid的上下两端虚拟两个site。默认其和第一行和最后一行是连通的。
  2. 由于采用了虚拟的site,引入了新问题:backwash。即isFull()会把下图右侧的也认为是full状态。解决办法:采取的解决办法是用两个并查集,多出来那个并查集只有上部的虚拟site,没有下部的。
  3. percolation.java和percolationStat.java的空间复杂度都超了。percolation:开始没有使用两个并查集时没超,用了结果就超了,不过超的不多。这里面有一个int[][],int是4个字节,改成了boolean[][],结果就不超了。对于percolationStat,超内存超了600多倍...猜测是我把一个临时变量定义成了全局的,所以在多次测试时,gc没有回收掉。后来每次使用后,将这个临时的引用赋值为null就好了。实际上,不应该使用全局,既然是临时变量,只需要在更小的作用域里声明就行了。

 

代码:

 1 import edu.princeton.cs.algs4.WeightedQuickUnionUF;
 2 
 3 public class Percolation {
 4     private WeightedQuickUnionUF UF;
 5     private WeightedQuickUnionUF UF1;
 6     private boolean[][] grid;
 7     private int N;
 8 
 9     // create N-by-N grid, with all sites blocked
10     public Percolation(int N) {
11         if (N < 1) {
12             throw new java.lang.IllegalArgumentException();
13         }
14         this.N = N;
15         grid = new boolean[N + 1][N + 1];
16         UF = new WeightedQuickUnionUF(N * N + 2);
17         UF1 = new WeightedQuickUnionUF(N * N + 1);
18     }
19 
20     // open site (row i, column j) if it is not open already
21     public void open(int i, int j) {
22         if (i < 1 || j < 1 || i > N || j > N) {
23             throw new java.lang.IndexOutOfBoundsException();
24         }
25         if (!grid[i][j]) {
26             if (i == 1) {
27                 UF.union(0, j);
28                 UF1.union(0, j);
29             }
30             if (i == N) {
31                 UF.union(N * N + 1, (i - 1) * N + j);
32             }
33             grid[i][j] = true;
34             // judge whether this is full or not
35             // left
36             if (j > 1) {
37                 if (isOpen(i, j - 1)) {
38                     UF.union((i - 1) * N + j, (i - 1) * N + j - 1);
39                     UF1.union((i - 1) * N + j, (i - 1) * N + j - 1);
40                 }
41             }
42             // right
43             if (j < N) {
44                 if (isOpen(i, j + 1)) {
45                     UF.union((i - 1) * N + j, (i - 1) * N + j + 1);
46                     UF1.union((i - 1) * N + j, (i - 1) * N + j + 1);
47                 }
48             }
49             // up
50             if (i > 1) {
51                 if (isOpen(i - 1, j)) {
52                     UF.union((i - 1) * N + j, (i - 1 - 1) * N + j);
53                     UF1.union((i - 1) * N + j, (i - 1 - 1) * N + j);
54                 }
55             }
56             // down
57             if (i < N) {
58                 if (isOpen(i + 1, j)) {
59                     UF.union((i - 1) * N + j, (i + 1 - 1) * N + j);
60                     UF1.union((i - 1) * N + j, (i + 1 - 1) * N + j);
61                 }
62             }
63         }
64     }
65 
66     // is site (row i, column j) open?
67     public boolean isOpen(int i, int j) {
68         if (i < 1 || j < 1 || i > N || j > N) {
69             throw new java.lang.IndexOutOfBoundsException();
70         }
71         if (grid[i][j]) {
72             return true;
73         }
74         return false;
75     }
76 
77     // is site (row i, column j) full?
78     public boolean isFull(int i, int j) {
79         if (i < 1 || j < 1 || i > N || j > N) {
80             throw new java.lang.IndexOutOfBoundsException();
81         }
82         if (grid[i][j])
83             if (UF1.connected(0, (i - 1) * N + j)) {
84                 return true;
85             }
86         return false;
87     }
88 
89     // does the system percolate?
90     public boolean percolates() {
91         return UF.connected(0, N * N + 1);
92     }
93 
94     // test client (optional)
95     public static void main(String[] args) {
96     }
97 }
 1 import edu.princeton.cs.algs4.StdIn;
 2 import edu.princeton.cs.algs4.StdRandom;
 3 import edu.princeton.cs.algs4.StdStats;
 4 
 5 public class PercolationStats {
 6     private double[] results;
 7     private double mean;
 8     private double stddev;
 9     private double confidenceLo;
10     private double confidenceHi;
11     private Percolation perc;
12 
13     // perform T independent experiments on an N-by-N grid
14     public PercolationStats(int N, int T) {
15         if (N < 1 || T < 1) {
16             throw new java.lang.IllegalArgumentException();
17         }
18         results = new double[T];
19         for (int i = 0; i < T; i++) {
20             perc = new Percolation(N);
21             int result = 0;
22             while (!perc.percolates()) {
23                 int x = StdRandom.uniform(N) + 1;
24                 int y = StdRandom.uniform(N) + 1;
25                 while (perc.isOpen(x, y)) {
26                     x = StdRandom.uniform(N) + 1;
27                     y = StdRandom.uniform(N) + 1;
28                 }
29                 perc.open(x, y);
30                 result++;
31             }
32             perc = null;
33             results[i] = result / (N * N * 1.0);
34         }
35         mean = StdStats.mean(results);
36         stddev = StdStats.stddev(results);
37         confidenceLo = mean - 1.96 * stddev / Math.sqrt(T);
38         confidenceHi = mean + 1.96 * stddev / Math.sqrt(T);
39     }
40 
41     // sample mean of percolation threshold
42     public double mean() {
43         return mean;
44     }
45 
46     // sample standard deviation of percolation threshold
47     public double stddev() {
48         return stddev;
49     }
50 
51     // low endpoint of 95% confidence interval
52     public double confidenceLo() {
53         return confidenceLo;
54     }
55 
56     // high endpoint of 95% confidence interval
57     public double confidenceHi() {
58         return confidenceHi;
59     }
60 
61     // test client (described below)
62     public static void main(String[] args) {
63         int N = StdIn.readInt();
64         int T = StdIn.readInt();
65         PercolationStats unittest = new PercolationStats(N, T);
66         System.out.println("mean                    = " + unittest.mean());
67         System.out.println("stddev                  = " + unittest.stddev());
68         System.out.println("95% confidence interval = "
69                 + unittest.confidenceLo() + ", " + unittest.confidenceHi());
70 
71     }
72 }

下面是提交结果 :)

 

posted @ 2015-09-11 17:52  一路绝尘  阅读(502)  评论(0编辑  收藏  举报