26. Remove Duplicates from Sorted Array

26. Remove Duplicates from Sorted Array

Question

Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same.

Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.

Return k* after placing the final result in the first k slots of *nums.

Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.

Solution

由于数组本身已经排序,只要比较当前nums中的元素是否大于上一个保存的数值就可以决定是否保留。
创建一个k记录遍历的位置,每次比较nums[k]与nums[i]的位置元素的大小,如果当前的nums[i]大于nums[k],则将k位置向后移动1,并将下一个位置记录为nums[i]。

最后返回k+1。

Code

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int removeDuplicates(int[] nums) {
int k = 0;
for(int i = 0; i < nums.length; i++){
if(nums[k] < nums[i]){
k++;
nums[k] = nums[i];
}
}
return k + 1;
}
}
1578. Minimum Time to Make Rope Colorful

1578. Minimum Time to Make Rope Colorful

Problem

Alice has n balloons arranged on a rope. You are given a 0-indexed string colors where colors[i] is the color of the i<sup>th</sup> balloon.

Alice wants the rope to be colorful. She does not want two consecutive balloons to be of the same color, so she asks Bob for help. Bob can remove some balloons from the rope to make it colorful. You are given a 0-indexed integer array neededTime where neededTime[i] is the time (in seconds) that Bob needs to remove the i<sup>th</sup> balloon from the rope.

Return the minimum time Bob needs to make the rope colorful.

Solution

滑动窗口,遍历字符串。
common用来记录连续颜色相同的个数,初始化为1。
如果当前字符与下一个字符相同,则窗口向右侧扩展,common++。
遍历时记录替换气球需要的最大时间maxTime和替换掉所有同色气球的总时间deleteTime。

如果common大于1,则总时间加上需要删除的时间(刨除最大时间maxTime)。
更新i为i + common。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int minCost(String colors, int[] neededTime) {
int i = 0, totalTime = 0;
char[] c = colors.toCharArray();
while(i < neededTime.length){
int common = 1, maxTime = neededTime[i], deleteTime = neededTime[i];
while(i + common < neededTime.length && c[i] == c[i + common]){
maxTime = Math.max(maxTime, neededTime[i + common]);
deleteTime += neededTime[i + common];
common++;
}
if(common > 1){
deleteTime -= maxTime;
totalTime += deleteTime;
}
i += common;
}
return totalTime;
}
}

609. Find Duplicate File in System

Question

Given a list paths of directory info, including the directory path, and all the files with contents in this directory, return all the duplicate files in the file system in terms of their paths. You may return the answer in any order.

A group of duplicate files consists of at least two files that have the same content.

A single directory info string in the input list has the following format:

  • "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

It means there are n files (f1.txt, f2.txt ... fn.txt) with content (f1_content, f2_content ... fn_content) respectively in the directory “root/d1/d2/.../dm". Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory.

The output is a list of groups of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:

  • "directory_path/file_name.txt"

Solution

使用StringBuffer对字符串进行处理。
采用HashMap建立内容和对应列表的映射。

遍历处理字符串,并添加到map中。
最后遍历map,如果对应的列表size大于1,则加入结果。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
public List<List<String>> findDuplicate(String[] paths) {
List<List<String>> res = new ArrayList<>();
HashMap<String, List<String>> map = new HashMap<>();

for(String path : paths){
StringBuffer folder = new StringBuffer();

int i = 0;
while(path.charAt(i) != ' '){
folder.append(path.charAt(i));
i++;
}
while(i < path.length()){
while(path.charAt(i) == ' ') i++;
StringBuffer filename = new StringBuffer();
while(i < path.length() && path.charAt(i) != '('){
filename.append(path.charAt(i));
i++;
}

StringBuffer content = new StringBuffer();
while(i < path.length() && path.charAt(i) != ')'){
content.append(path.charAt(i));
i++;
}
i++;
List<String> arr = map.getOrDefault(content.toString(), new ArrayList<String>());
arr.add(folder.toString() + '/' + filename);
map.put(content.toString(), arr);
}
}

for(String content : map.keySet()){
if(map.get(content).size() > 1) res.add(map.get(content));
}

return res;
}
}
42. Trapping Rain Water

42. Trapping Rain Water

Question

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

Solution

双指针,设置当前左侧的最大高度left和右侧的最大高度right。

分别从两侧遍历height[]数组,当出现更高的height时更新left和right。
否则记录left和right与height[i]的差值,并记录在数组waterLeft[]和waterRight[]中。

遍历两个数组,添加两者中的最小值到volume。

*由于单个参数只记录了一侧的最大值,因此最大值另一侧的水的体积会被多计算,因此分别从两侧遍历来获得最小值。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int trap(int[] height) {
int n = height.length, left = 0, right = 0, volume = 0;
int[] waterLeft = new int[n], waterRight = new int[n];

for(int i = 0; i < n; i++){
if(left <= height[i]) left = height[i];
else waterLeft[i] = left - height[i];
}

for(int i = n - 1; i >= 0; i--){
if(right <= height[i]) right = height[i];
else waterRight[i] = right - height[i];
}

for(int i = 0; i < n; i++){
volume += Math.min(waterLeft[i], waterRight[i]);
}

return volume;
}
}
1770. Max Score from Multiplication Operations

1770. Max Score from Multiplication Operations

Question

You are given two integer arrays nums and multipliers** **of size n and m respectively, where n >= m. The arrays are 1-indexed.

You begin with a score of 0. You want to perform exactly m operations. On the i<sup>th</sup> operation (1-indexed), you will:

  • Choose one integer x from **either the start or the end **of the array nums.
  • Add multipliers[i] * x to your score.
  • Remove x from the array nums.

Return *the maximum score after performing *m operations.

Solution

动态规划,dp[][]数组记录左边取的个数和右边取的个数。

从取1开始到取multipliers的长度位置开始遍历。
然后从left取0个开始,直到left取i个为止遍历。
计算对应的right指针位置。

注意访问数组时需要访问left和right的上一个位置。

如果left为0,则只能取右侧的上一个位置加上右侧的上一个数值乘以mul。
如果right为0,则只能取左侧的上一个位置加上左侧的上一个数值乘以mul。
否则取两者之间的最大值。

最后遍历数组中left + right和为m的位置,并返回最大值。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int maximumScore(int[] nums, int[] multipliers) {
int n = nums.length, m = multipliers.length;
int[][] dp = new int[m+1][m+1];

for(int i = 1; i <= m; i++){
int mul = multipliers[i-1];
for(int l = 0; l <= i; l++){
int r = i - l;
int iL = l - 1, iR = n - r;
if(l == 0) dp[l][r] = dp[l][r-1] + mul * nums[iR];
else if(r == 0) dp[l][r] = dp[l-1][r] + mul * nums[iL];
else dp[l][r] = Math.max(dp[l-1][r] + mul * nums[iL], dp[l][r-1] + mul * nums[iR]);
}
}
int ans = Integer.MIN_VALUE;
for(int l = 1; l <= m; l++){
int r = m - l;
ans = Math.max(ans, dp[l][r]);
}
return ans;
}
}
1457. Pseudo-Palindromic Paths in a Binary Tree

1457. Pseudo-Palindromic Paths in a Binary Tree

Question

Given a binary tree where node values are digits from 1 to 9. A path in the binary tree is said to be pseudo-palindromic if at least one permutation of the node values in the path is a palindrome.

Return the number of pseudo-palindromic paths going from the root node to leaf nodes.

Solution

用数组bin[]记录一个树枝上的节点。

回溯,遇到根节点则判断数组bin[]中是否只有0个或1个奇数的数字。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int res;
int[] bin;
public int pseudoPalindromicPaths (TreeNode root) {
res = 0;
bin = new int[10];
backtrack(root);
return res;
}

private void backtrack(TreeNode root){
if(root.left == null && root.right == null){
bin[root.val]++;
boolean flag = false;
for(int i = 0; i < bin.length; i++){
if(flag && (bin[i] & 1) == 1){
bin[root.val]--;
return;
}
else if((bin[i] & 1) == 1) flag = true;
}
res++;
bin[root.val]--;
return;
}
bin[root.val]++;
if(root.left != null) backtrack(root.left);
if(root.right != null) backtrack(root.right);
bin[root.val]--;
}
}
393. UTF-8 Validation

393. UTF-8 Validation

Question

Given an integer array data representing the data, return whether it is a valid UTF-8 encoding (i.e. it translates to a sequence of valid UTF-8 encoded characters).

A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:

  1. For a 1-byte character, the first bit is a 0, followed by its Unicode code.
  2. For an n-bytes character, the first n bits are all one’s, the n + 1 bit is 0, followed by n - 1 bytes with the most significant 2 bits being 10.

x denotes a bit in the binary form of a byte that may be either 0 or 1.

**Note: **The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data.

Solution

位运算,循环更新UTF头部的位置start。
getByte()方法用来计算位数。
check()方法用来检查从start+1开始直到位数结束是否二进制位数以10开头。
isStartWith10()方法使用掩码判断二进制是否以10开头。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
int[] dt;
final int MASK = 0b11000000;
public boolean validUtf8(int[] data) {
dt = data;
int start = 0;

while(start < data.length){
int bit = getByte(start);
if(bit == -1 || start + bit > data.length) return false;
if(!check(start, bit)) return false;
start += bit;
}
return true;
}

private int getByte(int start){
int bit = 5;
for(int i = 0; i < 8; i++){
if((dt[start] & 1) == 0) bit = 7 - i;
dt[start] >>= 1;
}
if(bit == 0) return 1;
else if(bit == 1 || bit > 4) return -1;
else return bit;
}

private boolean check(int start, int bit){
for(int i = start + 1; i < start + bit; i++) if(!isStartWith10(dt[i])) return false;
return true;
}

private boolean isStartWith10(int num){
return (num & MASK) == 0b10000000;
}
}
1383. Maximum Performance of a Team

1383. Maximum Performance of a Team

Question

You are given two integers n and k and two integer arrays speed and efficiency both of length n. There are n engineers numbered from 1 to n. speed[i] and efficiency[i] represent the speed and efficiency of the i<sup>th</sup> engineer respectively.

Choose at most k different engineers out of the n engineers to form a team with the maximum performance.

The performance of a team is the sum of their engineers’ speeds multiplied by the minimum efficiency among their engineers.

Return the maximum performance of this team. Since the answer can be a huge number, return it modulo 10<sup>9</sup><span> </span>+ 7.

Solution

排序,将所有工程师根据其效率降序排列。

此时遍历时后一个工程师的效率一定小于等于前一个工程师。

因此,此时遍历到每一个工程师,其前面所有的工程师的efficiency均大于等于其本身。
维护一个所有选取工程师的总速度ttSpd,每次计算并更新max的值。
用最小堆来维护选取的工程师速度,如果优先级队列的尺寸超过k-1,则poll掉队列内最低的速度。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
final int mod = (int) Math.pow(10, 9) + 7;
int[][] engineer = new int[n][2];

for(int i = 0; i < n; i++){
engineer[i][0] = speed[i];
engineer[i][1] = efficiency[i];
}

Arrays.sort(engineer, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return b[1] - a[1];
}
});

long max = 0, ttSpd = 0;

PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int i = 0; i < n; i++){
int s = engineer[i][0], e = engineer[i][1];
ttSpd += s;
max = Math.max(max, ttSpd * e);
pq.add(s);
if(pq.size() == k) ttSpd -= pq.poll();
}

return (int) (max % mod);
}
}

1996. The Number of Weak Characters in the Game

1996. The Number of Weak Characters in the Game

Question

You are playing a game that contains multiple characters, and each of the characters has two main properties: attack and defense. You are given a 2D integer array properties where properties[i] = [attack<sub>i</sub>, defense<sub>i</sub>] represents the properties of the i<sup>th</sup> character in the game.

A character is said to be weak if any other character has both attack and defense levels strictly greater than this character’s attack and defense levels. More formally, a character i is said to be weak if there exists another character j where attack<sub>j</sub><span> </span>> attack<sub>i</sub> and defense<sub>j</sub><span> </span>> defense<sub>i</sub>.

Return the number of weak characters.

Solution

本题与354. Russian Doll Envelopes相近。

首先对数组进行排序,根据角色的attack数值降序排序,如果两者的attack数值相等,则根据两者的defence升序排序。

记录一个遍历过的最大defence数值maxDefence,遍历数组,如果当前maxDef大于角色的防御值,则此时当前遍历角色的attack与defence均严格小于上一个计算的角色,因此count加一。
否则更新maxDef。

*由于attack是降序的,因此可以确定遍历时下一组数组的attack一定更弱。(由于相同attack的角色是根据defence升序排列,因此记录maxDef时会逐个更新maxDef的值。)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int numberOfWeakCharacters(int[][] properties) {
int count = 0, maxDef = Integer.MIN_VALUE;

Arrays.sort(properties, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
if(a[0] == b[0]) return a[1] - b[1];
return b[0] - a[0];
}
});

for(int[] character : properties){
if(maxDef > character[1]) count++;
else maxDef = character[1];
}
return count;
}
}
606. Construct String from Binary Tree

606. Construct String from Binary Tree

Question

Given the root of a binary tree, construct a string consisting of parenthesis and integers from a binary tree with the preorder traversal way, and return it.

Omit all the empty parenthesis pairs that do not affect the one-to-one mapping relationship between the string and the original binary tree.

Solution

DFS搜索,先序遍历到每个节点将其加入StringBuffer。
如果当前节点有左子节点或右子节点,则递归左子节点,并在前后添加一对括号。(如果有右子节点的情况即使左子节点为空也需要添加一对括号加以区别。)
如果当前节点有右子节点,则递归右子节点,并在前后添加一对括号。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
StringBuffer sb;
public String tree2str(TreeNode root) {
sb = new StringBuffer();
dfs(root);
return sb.toString();
}

private void dfs(TreeNode root){
if(root == null) return;
sb.append(root.val);

boolean hasLeft = root.left != null, hasRight = root.right != null;

if(hasLeft || hasRight) sb.append("(");
dfs(root.left);
if(hasLeft || hasRight) sb.append(")");

if(hasRight) sb.append("(");
dfs(root.right);
if(hasRight) sb.append(")");
}
}
814. Binary Tree Pruning

814. Binary Tree Pruning

Question

Given the root of a binary tree, return the same tree where every subtree (of the given tree) not containing a 1 has been removed.

A subtree of a node node is node plus every node that is a descendant of node.

Solution 1

DFS搜索,首先递归两个子节点。
在搜索时如果节点为0且两个子节点均为null,则返回null。否则返回节点本身。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode pruneTree(TreeNode root) {
if(root == null) return null;
root.left = pruneTree(root.left);
root.right = pruneTree(root.right);
if(root.left == null && root.right == null && root.val == 0) return null;
else return root;
}
}

Solution 2

DFS搜索,返回子节点和自己中是否包含1。
如果节点为null,则返回false。
如果自己为1,则返回true。
否则返回两个子节点中是否有true。

BFS搜索,根据每个节点的子节点是否包含1来决定左右子节点是否保存。
如果没有1,则将对应的子节点修改为null。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode pruneTree(TreeNode root) {
if(!hasOne(root)) return null;
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
TreeNode curr = q.poll();
if(hasOne(curr.left)) q.add(curr.left);
else curr.left = null;
if(hasOne(curr.right)) q.add(curr.right);
else curr.right = null;
}
return root;
}

private boolean hasOne(TreeNode root){
if(root == null) return false;
if(root.val == 1) return true;
else return hasOne(root.left) || hasOne(root.right);
}
}
429. N-ary Tree Level Order Traversal

429. N-ary Tree Level Order Traversal

Question

Given an n-ary tree, return the level order traversal of its nodes’ values.

Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples).

Solution

BFS搜索,层序遍历。
用level记录上一层的个数。
当队列不为空时,每次挤出level个节点,并将其子节点加入队列。
将当前层次的节点值加入列表。
最后更新level的数量。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;

public Node() {}

public Node(int _val) {
val = _val;
}

public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/

class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<Node> q = new LinkedList<>();
q.add(root);
int level = 1;

while(!q.isEmpty()){
List<Integer> arr = new ArrayList<>();
for(int i = 0; i < level; i++){
Node curr = q.poll();
for(Node child : curr.children){
q.offer(child);
}
arr.add(curr.val);
}
res.add(arr);
level = q.size();
}
return res;
}
}
967. Numbers With Same Consecutive Differences

967. Numbers With Same Consecutive Differences

Question

Return all non-negative integers of length n such that the absolute difference between every two consecutive digits is k.

Note that every number in the answer must not have leading zeros. For example, 01 has one leading zero and is invalid.

You may return the answer in any order.

Solution

回溯,每次传入上一个数字和剩余的位数。
全局变量sum记录加和。
DFS搜索,每次计算下一位的可行数字并递归。
用回溯维护sum的值。
如果剩余位数为1,则将当前的sum加入结果,并清零sum。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Solution {
List<Integer> res;
int sum;
public int[] numsSameConsecDiff(int n, int k) {
res = new ArrayList<>();
for(int i = 1; i < 10; i++){
sum = 0;
dfs(i, n, k);
}

int[] ret = new int[res.size()];
for(int i = 0; i < res.size(); i++){
ret[i] = res.get(i);
}
return ret;
}

private void dfs(int prev, int n, int k){
sum += prev;
if(n == 1){
res.add(sum);
return;
}

if(k == 0){
sum *= 10;
dfs(prev + k, n-1, k);
sum /= 10;
return;
}
if(prev + k < 10){
sum *= 10;
dfs(prev + k, n-1, k);
sum /= 10;
}
if(prev >= k){
sum *= 10;
dfs(prev - k, n-1, k);
sum /= 10;
}
}
}

637. Average of Levels in Binary Tree

637. Average of Levels in Binary Tree

Question

Given the root of a binary tree, return the average value of the nodes on each level in the form of an array. Answers within 10<sup>-5</sup> of the actual answer will be accepted.

Solution

BFS搜索,记录单层的总和sum和单层的个数count。
每次遍历一个层级的所有节点,并更新sum和count。
遍历完毕后将当层级的平均数加入列表,同时将sum和count清零。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new ArrayList<>();
Queue<TreeNode> q = new LinkedList<>();

double sum = 0, count = 0;
int level = 1;
q.add(root);

while(!q.isEmpty()){

for(int i = 0; i < level; i++){
TreeNode curr = q.poll();
if(curr.left != null) q.add(curr.left);
if(curr.right != null) q.add(curr.right);
count++;
sum += curr.val;
}
res.add(sum/count);
sum = 0;
count = 0;
level = q.size();
}
return res;
}
}
1448. Count Good Nodes in Binary Tree

1448. Count Good Nodes in Binary Tree

Question

Given a binary tree root, a node X in the tree is named good if in the path from root to X there are no nodes with a value greater than X.

Return the number of good nodes in the binary tree.

Solution

DFS搜索,每次传入当前分支的最大值。
如果当前值大于等于最大值,则count+1。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int count;
public int goodNodes(TreeNode root) {
count = 0;
dfs(root, Integer.MIN_VALUE);
return count;
}

private void dfs(TreeNode root, int max){
if(root == null) return;
if(root.val >= max){
count++;
max = root.val;
}

dfs(root.left, max);
dfs(root.right, max);
}
}