LeetCode-695
深度优先搜索 + 栈
算法:
我们可以用栈来实现深度优先搜索算法。这种方法本质与方法一相同,唯一的区别是:
方法一通过函数的调用来表示接下来想要遍历哪些土地,让下一层函数来访问这些土地。而方法二把接下来想要遍历的土地放在栈里,然后在取出这些土地的时候访问它们。
访问每一片土地时,我们将对围绕它四个方向进行探索,找到还未访问的土地,加入到栈 stack 中;
另外,只要栈 stack 不为空,就说明我们还有土地待访问,那么就从栈中取出一个元素并访问。
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int ans = 0;//记录最大陆地大小
//遍历每一个位置 提交错误,对了一下,两个for的迭代因子都是先++
for(int i = 0;i<grid.length;i++){
for(int j = 0;j<grid[0].length;j++){
int cur = 0;//用来记每块陆地大小
//两个栈
Deque<Integer> stacki = new LinkedList<Integer>();
Deque<Integer> stackj = new LinkedList<Integer>();
stacki.push(i);
stackj.push(j);
//只要i栈不为空就一直循环
while(!stacki.isEmpty()){
int cur_i = stacki.pop(),cur_j = stackj.pop();//弹出坐标栈的值
//对该点进行判断
if(cur_i<0||cur_j<0||cur_i==grid.length||cur_j==grid[0].length||grid[cur_i][cur_j]!=1){
continue;//开始下一轮循环
}
++cur;//没从判断出去,就是陆地,值+1
grid[cur_i][cur_j]=0;//置0
//找上下左右并进栈,这个while和for就很好的体现广度搜索,for循环里找的点都是同一个广度
int[] di = {0, 0, 1, -1};
int[] dj = {1, -1, 0, 0};
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
stacki.push(next_i);
stackj.push(next_j);
}
}
ans = Math.max(ans,cur);
}
}
return ans;//最后返回面积
}
}
方法三:广度优先搜索
算法:
我们把方法二中的栈改为队列,每次从队首取出土地,并将接下来想要遍历的土地放在队尾,就实现了广度优先搜索算法
就改了个队列
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int ans = 0;
for (int i = 0; i != grid.length; ++i) {
for (int j = 0; j != grid[0].length; ++j) {
int cur = 0;
Queue<Integer> queuei = new LinkedList<Integer>();
Queue<Integer> queuej = new LinkedList<Integer>();
queuei.offer(i);
queuej.offer(j);
while (!queuei.isEmpty()) {
int cur_i = queuei.poll(), cur_j = queuej.poll();
if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
continue;
}
++cur;// 等于1,就++,记录大小
grid[cur_i][cur_j] = 0;//置0
int[] di = {0, 0, 1, -1};
int[] dj = {1, -1, 0, 0};
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
queuei.offer(next_i);
queuej.offer(next_j);
}
}
ans = Math.max(ans, cur);
}
}
return ans;
}
}
LeetCode -617
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
//判断树是否为空
if (t1 == null) {
return t2;
}
if (t2 == null) {
return t1;
}
TreeNode merged = new TreeNode(t1.val + t2.val);
Queue<TreeNode> queue = new LinkedList<TreeNode>();//新树的队列
Queue<TreeNode> queue1 = new LinkedList<TreeNode>();
Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
queue.offer(merged);//新树的根节点
queue1.offer(t1);
queue2.offer(t2);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
//弹出活得新树和两颗树的根节点,因为要拿它去找其他结点
TreeNode node = queue.poll(), node1 = queue1.poll(), node2 = queue2.poll();
//两颗树结点的左右结点
TreeNode left1 = node1.left, left2 = node2.left, right1 = node1.right, right2 = node2.right;
//对左结点的处理
if (left1 != null || left2 != null) {//相同位置的两个结点有一个不为空
if (left1 != null && left2 != null) {
TreeNode left = new TreeNode(left1.val + left2.val);
node.left = left;
queue.offer(left);
queue1.offer(left1);
queue2.offer(left2);
} else if (left1 != null) {
node.left = left1;
} else if (left2 != null) {
node.left = left2;
}
}
//对右结点的处理
if (right1 != null || right2 != null) {
if (right1 != null && right2 != null) {
TreeNode right = new TreeNode(right1.val + right2.val);
node.right = right;
queue.offer(right);
queue1.offer(right1);
queue2.offer(right2);
} else if (right1 != null) {
node.right = right1;
} else {
node.right = right2;
}
}
}
return merged;//返回新树的根结点
}
}