算法Week1

查了很多资料,介绍的不太清楚。发个自己的版本。

import edu.princeton.cs.algs4.WeightedQuickUnionUF;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdIn;


public class Percolation
{
	private boolean[] status;    //  保存开关状态。     
	private final int gridLength;  
	private final int virTop;    // 2个虚拟点。 方便判断是否渗透。
	private final int virButton;
	private final WeightedQuickUnionUF wuf;
	private int number;
	
	
	
	public Percolation(int n)
	{
		gridLength = n;
		
		status = new boolean[n*n + 1];  // 第 0 个 索引 放弃不用,从 1 开始。所以 + 1.
		wuf = new WeightedQuickUnionUF(n*n + 2);    // 增加 2 个 虚拟点. 所以要 + 2 个位置
		
		virButton = n*n + 1;  // 底部虚拟点放置在最后一位
		virTop = 0;           // 顶部虚拟点用第一个位置。
	}
	
	private int Real_Index(int row,int col)   { return (row - 1)*gridLength + col;}// 二维转 一维索引。从1开始,col不需要减1.
	
	private void Check(int row,int col)    // 检查坐标的有效性。
	{
		if(row < 1 || row > gridLength)  throw new IllegalArgumentException("row must be positive");
		
		if(col < 1 || col > gridLength)  throw new IllegalArgumentException("col must be positive");
		
	}
	
	public void open(int row,int col)
	{
		Check(row,col);  // 先检查 坐标是否有效。
		
		int index = Real_Index(row,col);
		
		status[index] = true;   // 打开此位置
		
		number++;
		
		int neiberhood;   // 开始检查上下左右的邻居   判断是否可以union
		 
		if(row == 1)  wuf.union(Real_Index(row,col),virTop);   // 当方块在第一行时, 将其与上方的虚拟点union.
		
		if(row == gridLength)  wuf.union(Real_Index(row,col),virButton);  // 当方块在最后一行时, 与下方的虚拟点union。
		
		if(row > 1){
			Check(row-1,col);   //下
			neiberhood = Real_Index(row-1,col);
			if(status[neiberhood])               wuf.union(neiberhood,index);
				
		}
		
		if(row < gridLength){
			Check(row+1,col);  // 上
			neiberhood = Real_Index(row+1,col);
			if(status[neiberhood])               wuf.union(neiberhood,index);
		}
		
		if(col > 1){
			Check(row,col-1);   // 左
			neiberhood = Real_Index(row,col-1);
			if(status[neiberhood])               wuf.union(neiberhood,index);
			}
			
		if(col < gridLength){
			Check(row,col+1);  // 右
			neiberhood = Real_Index(row,col+1);
			if(status[neiberhood])               wuf.union(neiberhood,index);
		}
		
		
	}
	
	public int numberOfOpenSites()  {return number;}
	
	public boolean isOpen(int row,int col){
		Check(row,col);
		
		return status[Real_Index(row,col)];
	}
	
	public boolean isFull(int row,int col){
		Check(row,col);
		
		return wuf.connected(Real_Index(row,col),virTop);
	}
	
	public boolean percolates()  {return wuf.connected(virButton,virTop);}   // 判断2个虚拟点是否 union.
	
	
	public static void main(String[] args){
		int N = StdIn.readInt();
		Percolation percola = new Percolation(N);
		percola.open(1,1);
		percola.open(2,1);
		if(percola.wuf.connected(percola.Real_Index(1,1),percola.Real_Index(2,1)))
			StdOut.println("Successful!");
	}
}

  PercolationStats 只要按照公式就行了。

  关键要理解union-find 的 应用。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值