JavaScript|LeetCode|搜索|417.太平洋大西洋水流问题

法1:DFS|顺流(从陆地到海洋)
想法:

  1. 遍历每一块陆地
  2. 对于某陆地:
  • 进行DFS,符合下列条件则可达:
    1)比当前陆地低/相等的陆地
    2)上下左右相邻陆地
  • 对可达陆地进行标记
  • 标记结束之后:遍历上下左右边界,左上边界有标记则可达太平洋,右下边界可达大西洋
  • 可达太平洋和大西洋,则存下该陆地坐标
  1. 另用以矩阵保存标记
/** * @param {number[][]} matrix * @return {number[][]} */
var pacificAtlantic = function(matrix) {
    if(matrix.length == 0) {        
        return [];    
    }    
    var output = []; // 输出,存所求陆地坐标    
    var temp = [], temp1 = []; // temp为标记;temp1作用:方便标记;true可达,false不可达    
    var i = 0, j = 0, k = 0, l = 0; // 用于遍历    
    // 后续多次求以下两值,存在两个变量中,耗时更短    
    var row = matrix.length, column = matrix[0].length;
    // temp:标记;矩阵matrix相应位置为false,不可达;为true,可达    
    for(i = 0; i < row; i++) {        
        for(j = 0; j < column; j++) {            
            temp1[temp1.length] = false;        
        }        
        temp.push(temp1);        
        temp1 = [];    
    }        

    for(i = 0; i < row; i++) {        
        for(j = 0; j < column; j++) {            
            dfs(matrix, i, j, temp);            
            if(arrived(temp)) { // arrived()检验标记结束之后的temp                
                output[output.length] = [i, j];            
            }            
            temp = [];            
            for(k = 0; k < row; k++) {                
                for(l = 0; l < column; l++) {                    
                    temp1[temp1.length] = false;                
                }                
                temp.push(temp1);                
                temp1 = [];            
            }        
        }    
    }    
    return output;
};

function dfs(matrix, r, c, temp) {    
    var i = 0, j = 0;    
    temp[r][c] = true; // 标记    
    for(i = -1; i < 2; i++) {        
        for(j = -1; j < 2; j++) {            
            if(i == j || i * j == -1) { // 只访问上下左右                
                continue;            
            }            
            if(r + i < 0 || r + i >= matrix.length ||
            		 c + j < 0 || c + j >= matrix[0].length) { // 下标越界则continue                
                continue;            
            }            
            if((!temp[r + i][c + j]) && 
            		(matrix[r + i][c + j] <= matrix[r][c])) {                
                dfs(matrix, r + i, c + j, temp);            
            }        
        }  
    }
}

function arrived(temp) {    
    var i = 0, row = temp.length, column = temp[0].length;    
    var pacific = false, atlantic = false;
    for(i = 0; i < column; i++) {        
        if(temp[0][i]) { // 上边界            
            pacific = true;        
        }        
        if(temp[row - 1][i]) { // 下边界            
            atlantic = true;        
        }    
    }
    for(i = 0; i < row; i++) {        
        if(temp[i][0]) { // 左边界            
            pacific = true;        
        }        
        if(temp[i][column - 1]) { // 右边界            
            atlantic = true;        
        }    
    }    
    return pacific && atlantic; // 返回是否可达太平洋和大西洋
}

法2:DFS|逆流(从海洋到陆地)
-看了看题解,发现从边界到陆地可行。

想法:

  1. 从边界到中央:遍历边界陆地
  2. 上左边界为太平洋,从两边界开始遍历,得到矩阵 pacific:
  • 进行DFS,符合下列条件则可达:
    1)比当前陆地高/相等的陆地
    2)上下左右相邻陆地
  • 对可达陆地进行标记:true可达,false不可达
  1. 下右边界为大西洋,从两边界开始遍历,得到矩阵 atlantic(同2)
  2. 标记结束之后:遍历pacific和atlantic矩阵,同为true的坐标则存下
/** * @param {number[][]} matrix * @return {number[][]} */
var pacificAtlantic = function(matrix) { 
// 法2 从边界到中央    
// 上左边界为太平洋,从两边界开始遍历,得到矩阵 pacific    
// 下右边界为大西洋,从两边界开始遍历,得到矩阵 atlantic    
// 取pacific和atlantic的交集,即答案    
    if(matrix.length == 0) {        
        return [];    
    }    
    var pacific = [], atlantic = [], temp = [], output = [];    
    var i = 0, j = 0, row = matrix.length, column = matrix[0].length;    
    for(i = 0; i < row; i++) {        
        for(j = 0; j < column; j++) {            
            temp[temp.length] = false;        
        }        
        pacific[pacific.length] = temp; // 是否可达大平洋        
        temp = [];    
    }    
    for(i = 0; i < row; i++) {        
        for(j = 0; j < column; j++) {            
            temp[temp.length] = false;        
        }        
        atlantic[atlantic.length] = temp; // 是否可达大西洋        
        temp = [];    
    }
    for(i = 0; i < row; i++) { // 左右边界         
        dfs(matrix, i, 0, pacific);        
        dfs(matrix, i, column - 1, atlantic);    
    }
    for(i = 0; i < column; i++) { // 上下边界        
        dfs(matrix, 0, i, pacific);        
        dfs(matrix, row - 1, i, atlantic);    
    }
    for(i = 0; i < row; i++) {         
        for(j = 0; j < column; j++) {            
            if(pacific[i][j] && atlantic[i][j]) {                
                output[output.length] = [i, j];            
            }        
        }    
    }    
    return output;
};

function dfs(matric, r, c, arrived) {    
    arrived[r][c] = true;    
    var i = 0, j = 0;    
    for(i = -1; i < 2; i++) {        
        for(j = -1; j < 2; j++) {            
            if(i == j || i * j == -1) {                
                continue;            
            }            
            if(r + i < 0 || r + i >= matric.length || c + j < 0 
                   || c + j >= matric[0].length) {                
                continue;            
            }            
            if(!arrived[r + i][c + j] &&                     
                    (matric[r + i][c + j] >= matric[r][c])) {                
                dfs(matric, r + i, c + j, arrived);            
            }        
        }    
    }
}
发布了7 篇原创文章 · 获赞 0 · 访问量 101

猜你喜欢

转载自blog.csdn.net/J_learner/article/details/104650846