1.這是在Leetcode上的一道題,我們去看一下它的題目
實現過程比較簡單,因爲代碼會在LeetCode裏面提交,我們就不用自己的寫的棧和鏈表了,我們學習使用一下Java的內部棧對象和動態數組
以下代碼是通過LeetCode測試的代碼。
/*
* @lc app=leetcode.cn id=1020 lang=java
*
* [1020] 飛地的數量
*/
// @lc code=start
class Solution {
public int numEnclaves(int[][] A) {
FlyLandProblem fs = new FlyLandProblem(A);
int sum = fs.dfs();
return sum;
}
}
interface Element<T> {
Element getNext();
void setNext(Element t);
T getValue();
void setValue(T t);
}
interface IVector2Element<T> extends Element<T> {
int getX();
int getY();
IVector2Element last();
void setLast(IVector2Element t);
}
class Vector2<T> implements IVector2Element<T> {
Element last;
Element next;
int x;
int y;
T value;
public Vector2(int x,int y,T value){
this.x = x;
this.y = y;
this.value = value;
}
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return y;
}
@Override
public IVector2Element last() {
return (IVector2Element)last;
}
@Override
public void setLast(IVector2Element t) {
last = t;
}
@Override
public Element getNext() {
return (IVector2Element)next;
}
@Override
public void setNext(Element t) {
this.next = t;
}
@Override
public T getValue() {
return this.getValue();
}
@Override
public void setValue(T t) {
this.value = t;
}
}
class FlyLandElement extends Vector2<Integer> {
public FlyLandElement(int x, int y, Integer value) {
super(x, y, value);
statu = false;
}
public boolean statu;
public boolean isBorder(int w,int h){
if (x ==0){
return true;
}
if (x==w-1){
return true;
}
if (y == 0){
return true;
}
if (y==h-1){
return true;
}
return false;
}
public ArrayList<FlyLandElement> nextDirArray(int[][] data, int[][] label, int w, int h){
ArrayList<FlyLandElement> tt = new ArrayList<>();
if (x - 1>=0){
if (data[x-1][y] == 1&&label[x-1][y]!= 100){
FlyLandElement tl = new FlyLandElement(x-1,y,data[x-1][y]);
tl.setLast(this);
tt.add(tl);
}
}
if (x+1<h){
if (data[x+1][y] == 1&&label[x+1][y]!= 100){
FlyLandElement tl = new FlyLandElement(x+1,y,data[x+1][y]);
tl.setLast(this);
tt.add(tl);
}
}
if (y-1>=0){
if (data[x][y-1] == 1&&label[x][y-1]!= 100){
FlyLandElement tl = new FlyLandElement(x,y-1,data[x][y-1]);
tl.setLast(this);
tt.add(tl);
}
}
if (y+1<w){
if (data[x][y+1]== 1&&label[x][y+1]!= 100){
FlyLandElement tl =new FlyLandElement(x,y+1,data[x][y+1]);
tl.setLast(this);
tt.add(tl);
}
}
return tt;
}
}
class FlyLandProblem {
int h;
int w;
int[][] label ;
int[][] data;
int len;
int[][] endData;
//java的棧
Stack<FlyLandElement> ost ;
public FlyLandProblem(int[][] data) {
this.data = data;
h = data.length;
w = data[0].length;
label = new int[h][w];
ost = new Stack<>();
endData = new int[h][w];
for (int i =0;i<h;i++){
for (int j = 0;j<w;j++){
endData[i][j] = data[i][j];
label[i][j] = 0;
if (i == 0||j == 0||i==h-1||j==w-1){
if (data[i][j] == 1){
FlyLandElement land = new FlyLandElement(i,j,data[i][j]);
ost.push(land);
len++;
}
}
}
}
}
public int line = 0;
public int dfs(){
while (ost.size()>0){
FlyLandElement fe = ost.pop();
if (label[fe.getX()][fe.getY()] == 100){
continue;
}
label[fe.getX()][fe.getY()] = 100;
ArrayList<FlyLandElement> nextPoint = fe.nextDirArray(data,label,w,h);
for (int i =0;i<nextPoint.size();i++){
FlyLandElement el = nextPoint.get(i);
if (label[el.getX()][el.getY()] == 100){
//如果被訪問過則不會被訪問
continue;
}
ost.push(el);
}
if (fe.nextDirArray(data,label,w,h).size()==0){
FlyLandElement se = fe;
while (se!= null){
endData[se.getX()][se.getY()] = 4;
se = (FlyLandElement)se.last();
}
line++;
}
}
String va = "";
int sum = 0;
// System.out.println(se.getX()+"<"+line+">"+se.getY());
for (int i =0;i<h;i++) {
for (int j = 0; j < w; j++) {
if (endData[i][j] == 1){
sum+= 1;
}
}
}
return sum;
}
}
// @lc code=end
這個是LeetCode的性能評價。
我感覺我創造了一個記錄,這個記錄不是很妙,哈哈~
實現思路其實相當簡單:
獲取所有邊緣的地,往裏面搜,對所有能夠搜索到的路徑標記爲可通過,最後返回無法搜索的地的數量。
這就是棧的深度優先的魅力。
當然,爲什麼我會使用那麼多的內存,核心因素在於,我在實現這個算法的過程中,每一條路徑都會產生一個新的節點,這樣其實不是很好,節點多了,那麼內存就多了。
哈哈~