力扣(LeetCode)934

Linus脫襪子發表於2019-01-19

題目地址:
https://leetcode-cn.com/probl…
題目描述:
在給定的二維二進位制陣列 A 中,存在兩座島。(島是由四面相連的 1 形成的一個最大組。)

現在,我們可以將 0 變為 1,以使兩座島連線起來,變成一座島。

返回必須翻轉的 0 的最小數目。(可以保證答案至少是 1。)

解答:
題的意思就是說,有兩片島嶼,島嶼是指聯通的1組成的區域,求這兩片島嶼之間的最短距離。
思路是這樣的,用圖的深度優先搜尋dfs演算法,來找出第一個島嶼裡的全部點,加入list1,然後
同樣的方法找到第二個島嶼的全部點,加入list2,然後求list1中任意一點到list2中任意一點
距離的最小值即可,這裡的距離是指abs(x1-x2)+abs(y1-y2)-1
abs為絕對值,x1,y1為list1的某點的座標,x2,y2為list2的某點座標。
這一題考察的是圖的深度優先搜尋
java ac程式碼:

class Solution {

class Node
{
    int x,y;
    public Node(int x,int y)
    {
        this.x = x;
        this.y = y;
    }
}

public int shortestBridge(int[][] A) {
    
    boolean[][] visited = new boolean[A.length][A[0].length];
    List<Node> l1 = new ArrayList(1000);
    List<Node> l2 = new ArrayList(1000);
    
    
    for(int i = 0;i < A.length;i++)
    {
        boolean flag = false;
        for(int j = 0;j < A[0].length;j++)
            if(A[i][j] == 1&&!visited[i][j]){
                dfs(A,visited,i,j,l1);
                flag = true;
                break;
            }
        if(flag)break;
    }
    
   for(int i = 0;i < A.length;i++)
    {
        boolean flag = false;
        for(int j = 0;j < A[0].length;j++)
            if(A[i][j] == 1&&!visited[i][j]){
                dfs(A,visited,i,j,l2);
                flag = true;
                break;
            }
        if(flag)break;
    }
    
    
    int ans = Integer.MAX_VALUE;
    
     for(int i = 0;i < l1.size();i++)
        for(int j = 0;j < l2.size();j++)
           ans = Math.min(ans,Math.abs(l1.get(i).x-l2.get(j).x)+Math.abs(l1.get(i).y-l2.get(j).y)-1);
            
    
    return ans;
    
    
}


void dfs(int[][] A,boolean[][] visited,int x,int y,List<Node> l)
{
    if(!(x >= 0&&x < A.length&& y>=0 && y< A[0].length) || visited[x][y]||A[x][y] !=1 )
        return;
    
    visited[x][y] = true;
    l.add(new Node(x,y));
    dfs(A,visited,x-1,y,l);
    dfs(A,visited,x+1,y,l);
    dfs(A,visited,x,y-1,l);
    dfs(A,visited,x,y+1,l);
    
}

}

用時400多ms,如果用python可能會超時。

相關文章