这个问题和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8。
arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。我们最多能将数组分成多少块?
排序块的充分条件是:此块中最大数字为 headhead , 若此块后面的所有数字都 >= head ,则此块为排序块。
可以遍历一遍数组arr,动态判断到目前数字 num 为止最多能分出多少排序块,并保存每个排序块的最大值 head 。每遍历到下个数字 num,动态判断前面所有的排序块是否成立,并更新所有排序块:
class Solution {
public int maxChunksToSorted(int[] arr) {
LinkedList<Integer> stack = new LinkedList<Integer>();
for(int num : arr) {
if(!stack.isEmpty() && num < stack.getLast()) {
int head = stack.removeLast();
while(!stack.isEmpty() && num < stack.getLast()) stack.removeLast();
stack.addLast(head);
}
else stack.addLast(num);
}
return stack.size();
}
}
class Solution {
public int maxChunksToSorted(int[] arr) {
if (arr.length == 0) return 0;
int[] rightMin = new int[arr.length];
int leftMax = arr[0];
rightMin[arr.length-1] = arr[arr.length-1];
for (int i = arr.length-2; i >= 0 ; i--) {
rightMin[i] = Math.min(arr[i], rightMin[i+1]);
}
int res = 1;
for (int i = 1; i < arr.length; i++) {
if (leftMax <= rightMin[i]) res++;
leftMax = Math.max(leftMax, arr[i]);
}
return res;
}
}
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
DFS。扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。最终岛屿的数量就是我们进行深度优先搜索的次数。
class Solution {
public int numIslands(char[][] grid) {
if (grid.length == 0 || grid[0].length == 0) return 0;
int lines = grid.length;
int rows = grid[0].length;
int ans = 0;
for (int i = 0; i < lines; i++) {
for (int j = 0; j < rows; j++) {
if (grid[i][j] == '1')
{
traceback(grid, i, j);
ans++;
}
}
}
return ans;
}
private void traceback(char[][] grid, int i, int j) {
if (i<0 || i>=grid.length || j<0 || j>=grid[0].length || grid[i][j] == '0') return;
grid[i][j] = '0';
traceback(grid, i-1, j);
traceback(grid, i+1, j);
traceback(grid, i, j-1);
traceback(grid, i, j+1);
}
}
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
DFS。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
PreOrder(root, res);
return res;
}
private void PreOrder(TreeNode root, List<Integer> res) {
if (root == null) return;
res.add(root.val);
PreOrder(root.left, res);
PreOrder(root.right, res);
}
}