题目大概是这个意思:给定一个n*m的数组,找到每一条能从左上角探索到左下角的path,然后每一条path里找到最小值,所有这些最小值合在一起,看最大值是哪个。
举个例子:
[8, 4, 7]
[6, 5, 9]
有3条path:
8-4-7-9 min: 4
8-4-5-9 min: 4
8-6-5-9 min: 5
return: 5
这道题看地理大家激烈的讨论,说拿DP可以做?但是我觉得不行啊,DP的话只能new一个对应的数组,然后一边探索一边更新这个数组,而且注定要recursive。但是问题是,你怎么能一边一直取最小值,到最后一个点又取最大值呢?倒是维护一下也可以,但是地理几位仁兄提的直接dp的实在不敢苟同,他们的方法更像是每个dp的grid都记录之前点最小值中的最大值,那到最后一个grid的时候很多之前的min已经被覆盖了啊!我稍后会尝试做一下正确的dp能不能写出来,只dp到最后一个点的时候要加判断。
我觉得更concise的是用DFS,思路非常清晰,就是一直深度探索,遍历每一个点,然后一路下来保持最小值,到最后一个点与之前的最小值比谁大,谁大谁留下。
写了代码like this:
public int maxMin(int[][] matrix){
if(matrix==null||matrix.length==0||matrix[0].length==0)
return 0;
max = Integer.MIN_VALUE;
dfs(matrix,0,0,Integer.MAX_VALUE);
return max;
}
private void dfs(int[][] mat, int i, int j, int minSoFar){
int m = mat.length , n = mat[0].length;
//base case: reach out of bottom right
if(i==m||n==j)
return;
//every new step, evaluate current node and previous min
minSoFar = Math.min(mat[i][j], minSoFar);
//when reach final grid, return the bigger one
if(i==m-1 && j==n-1) {
max = Math.max(minSoFar, max);
}
dfs(mat, i+1, j, minSoFar);
dfs(mat, i, j+1, minSoFar);
}
这里写给自己DFS的关键思想:
1. 写base case,探索到最后了要怎么办。这道题目就是,return,再往下不用管了。
2. 写正常的非base case你要怎么操作。这道理里就是更新到这个点的最小值,是目前为止的最小值还是这个点更小。
3. 如果有特殊需求,加if写。在这道理里就是如果探索到最后一个点了,开始判断最大值。
4. DFS都是recursive,继续探索下面的level。