Skip to content

Commit

Permalink
feat: add solution to lc/lcof2 problem: Find Largest Value in Each Tree
Browse files Browse the repository at this point in the history
Row
  • Loading branch information
yanglbme committed Sep 15, 2021
1 parent 335333e commit ae5883f
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 39 deletions.
42 changes: 31 additions & 11 deletions basic/searching/BinarySearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,57 @@

二分的本质并非“单调性”,而是“边界”,只要找到某种性质,使得整个区间一分为二,那么就可以用二分把边界点二分出来。

**整数二分算法模板:**
## 算法模板

### 模板 1

```java
/** 检查x是否满足某种性质 */
boolean check(int x) {}

/** 区间[left, right]被划分成[left, mid]和[mid + 1, right]时使用 */
int binarySearch1(int left, int right) {
int search(int left, int right) {
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) right = mid;
else left = mid + 1;
if (check(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
```

### 模板 2

```java
boolean check(int x) {}

/** 区间[left, right] 被划分成[left, mid - 1]和[mid, right]时使用 */
int binarySearch2(int left, int right) {
int search(int left, int right) {
while (left < right) {
int mid = (left + right + 1) >> 1;
if (check(mid)) left = mid;
else right = mid - 1;
if (check(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
```

我们做二分题目时,可以按照以下步骤:

1. 写出循环条件:`while (left < right)`,注意是 `left < right`,而非 `left <= right`
1. 循环体内,先无脑写出 `mid = (left + right) >> 1`
1. 根据具体题目,实现 `check()` 函数(有时很简单的逻辑,可以不定义函数),想一下究竟要用 `left = mid`(模板二) 还是 `right = mid`(模板一);
- 如果 `left = mid`,那么无脑写出 else 语句 `right = mid - 1`,并且在 mid 计算时补充 +1,即 `mid = (left + right + 1) >> 1`
- 如果 `right = mid`,那么无脑写出 else 语句 `left = mid + 1`,并且不需要更改 mid 的计算;
1. 循环结束时,left 与 right 相等。

## 例题

- [在排序数组中查找元素的第一个和最后一个位置](/solution/0000-0099/0034.Find%20First%20and%20Last%20Position%20of%20Element%20in%20Sorted%20Array/README.md)
- [x 的平方根](/solution/0000-0099/0069.Sqrt%28x%29/README.md)
- [寻找峰值](/solution/0100-0199/0162.Find%20Peak%20Element/README.md)
- [第一个错误的版本](/solution/0200-0299/0278.First%20Bad%20Version/README.md)
- [不动点](/solution/1000-1099/1064.Fixed%20Point/README.md)
- [不动点](/solution/1000-1099/1064.Fixed%20Point/README.md)
33 changes: 22 additions & 11 deletions basic/searching/BinarySearch/README_EN.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
# Binary Search

**Algorithm Templates:**
## Algorithm Templates

### Template 1

```java
/** check x if valid */
boolean check(int x) {}

/** template1 */
int binarySearch1(int left, int right) {
int search(int left, int right) {
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) right = mid;
else left = mid + 1;
if (check(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
```

### Template 1

```java
boolean check(int x) {}

/** template2 */
int binarySearch2(int left, int right) {
int search(int left, int right) {
while (left < right) {
int mid = (left + right + 1) >> 1;
if (check(mid)) left = mid;
else right = mid - 1;
if (check(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
Expand All @@ -33,4 +44,4 @@ int binarySearch2(int left, int right) {
- [Sqrt(x)](/solution/0000-0099/0069.Sqrt%28x%29/README_EN.md)
- [Find Peak Element](/solution/0100-0199/0162.Find%20Peak%20Element/README_EN.md)
- [First Bad Version](/solution/0200-0299/0278.First%20Bad%20Version/README_EN.md)
- [Fixed Point](/solution/1000-1099/1064.Fixed%20Point/README_EN.md)
- [Fixed Point](/solution/1000-1099/1064.Fixed%20Point/README_EN.md)
82 changes: 73 additions & 9 deletions lcof2/剑指 Offer II 044. 二叉树每层的最大值/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,86 @@

<!-- 这里可写通用的实现逻辑 -->

“BFS 层次遍历”实现。

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def largestValues(self, root: TreeNode) -> List[int]:
if root is None:
return []
q = collections.deque([root])
res = []
while q:
n = len(q)
t = float('-inf')
for _ in range(n):
node = q.popleft()
t = max(t, node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
res.append(t)
return res
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java

/**
* 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<Integer> largestValues(TreeNode root) {
if (root == null) {
return Collections.emptyList();
}
Deque<TreeNode> q = new ArrayDeque<>();
q.offer(root);
List<Integer> res = new ArrayList<>();
while (!q.isEmpty()) {
int t = Integer.MIN_VALUE;
for (int i = 0, n = q.size(); i < n; ++i) {
TreeNode node = q.poll();
t = Math.max(t, node.val);
if (node.left != null) {
q.offer(node.left);
}
if (node.right != null) {
q.offer(node.right);
}
}
res.add(t);
}
return res;
}
}
```

### **C++**
Expand All @@ -100,32 +164,32 @@ class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> res;
if( !root )
if (!root)
{
return res;
}

deque<TreeNode* > deq;
deque<TreeNode *> deq;
deq.push_back(root);
while( !deq.empty())
while (!deq.empty())
{
int size = deq.size();
int maxnum = INT_MIN;
for (int i = 0; i < size; i++)
{
TreeNode* ptr = deq.front();
TreeNode *ptr = deq.front();
deq.pop_front();
if(maxnum < ptr->val)
if (maxnum < ptr->val)
{
maxnum = ptr->val;
}

if(ptr->left)
if (ptr->left)
{
deq.push_back(ptr->left);
}

if(ptr->right)
if (ptr->right)
{
deq.push_back(ptr->right);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> largestValues(TreeNode *root) {
vector<int> res;
if( !root )
if (!root)
{
return res;
}

deque<TreeNode* > deq;
deque<TreeNode *> deq;
deq.push_back(root);
while( !deq.empty())
while (!deq.empty())
{
int size = deq.size();
int maxnum = INT_MIN;
for (int i = 0; i < size; i++)
{
TreeNode* ptr = deq.front();
TreeNode *ptr = deq.front();
deq.pop_front();
if(maxnum < ptr->val)
if (maxnum < ptr->val)
{
maxnum = ptr->val;
}

if(ptr->left)
if (ptr->left)
{
deq.push_back(ptr->left);
}

if(ptr->right)
if (ptr->right)
{
deq.push_back(ptr->right);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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<Integer> largestValues(TreeNode root) {
if (root == null) {
return Collections.emptyList();
}
Deque<TreeNode> q = new ArrayDeque<>();
q.offer(root);
List<Integer> res = new ArrayList<>();
while (!q.isEmpty()) {
int t = Integer.MIN_VALUE;
for (int i = 0, n = q.size(); i < n; ++i) {
TreeNode node = q.poll();
t = Math.max(t, node.val);
if (node.left != null) {
q.offer(node.left);
}
if (node.right != null) {
q.offer(node.right);
}
}
res.add(t);
}
return res;
}
}
24 changes: 24 additions & 0 deletions lcof2/剑指 Offer II 044. 二叉树每层的最大值/Solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def largestValues(self, root: TreeNode) -> List[int]:
if root is None:
return []
q = collections.deque([root])
res = []
while q:
n = len(q)
t = float('-inf')
for _ in range(n):
node = q.popleft()
t = max(t, node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
res.append(t)
return res
Loading

0 comments on commit ae5883f

Please sign in to comment.