Merge branch 'master' of github.com:youngyangyang04/leetcode-master

This commit is contained in:
programmercarl
2022-09-16 09:40:32 +08:00
22 changed files with 445 additions and 189 deletions

View File

@ -9,7 +9,7 @@
# 28. 实现 strStr()
[力扣题目链接](https://leetcode.cn/problems/implement-strstr/)
[力扣题目链接](https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/)
实现 strStr() 函数。
@ -699,7 +699,7 @@ class Solution(object):
if haystack[i:i+n]==needle:
return i
return -1
```
```
```python
// 方法一
class Solution:

View File

@ -160,73 +160,34 @@ class Solution {
```
## Python
>直接使用sorted()不符合题意
>直接使用sorted()会开辟新的空间并返回一个新的list故补充一个原地反转函数
```python
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
for i in range(len(nums)-1, -1, -1):
for j in range(len(nums)-1, i, -1):
if nums[j] > nums[i]:
nums[j], nums[i] = nums[i], nums[j]
nums[i+1:len(nums)] = sorted(nums[i+1:len(nums)])
return
nums.sort()
```
>另一种思路
```python
class Solution:
'''
抛砖引玉因题目要求“必须原地修改只允许使用额外常数空间”python内置sorted函数以及数组切片+sort()无法使用。
故选择另一种算法暂且提供一种python思路
'''
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
length = len(nums)
for i in range(length-1, 0, -1):
if nums[i-1] < nums[i]:
for j in range(length-1, 0, -1):
if nums[j] > nums[i-1]:
nums[i-1], nums[j] = nums[j], nums[i-1]
break
self.reverse(nums, i, length-1)
break
if n == 1:
# 若正常结束循环,则对原数组直接翻转
self.reverse(nums, 0, length-1)
def reverse(self, nums: List[int], low: int, high: int) -> None:
while low < high:
nums[low], nums[high] = nums[high], nums[low]
low += 1
high -= 1
```
>上一版本简化版
```python
class Solution(object):
def nextPermutation(self, nums: List[int]) -> None:
n = len(nums)
i = n-2
while i >= 0 and nums[i] >= nums[i+1]:
i -= 1
if i > -1: // i==-1,不存在下一个更大的排列
j = n-1
while j >= 0 and nums[j] <= nums[i]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
for i in range(length - 1, -1, -1):
for j in range(length - 1, i, -1):
if nums[j] > nums[i]:
nums[j], nums[i] = nums[i], nums[j]
self.reverse(nums, i + 1, length - 1)
return
self.reverse(nums, 0, length - 1)
start, end = i+1, n-1
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
return nums
def reverse(self, nums: List[int], left: int, right: int) -> None:
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
"""
265 / 265 个通过测试用例
状态:通过
执行用时: 36 ms
内存消耗: 14.9 MB
"""
```
## Go

View File

@ -258,40 +258,45 @@ public:
**使用标记数组**
```Java
class Solution {
List<List<Integer>> lists = new ArrayList<>();
Deque<Integer> deque = new LinkedList<>();
int sum = 0;
LinkedList<Integer> path = new LinkedList<>();
List<List<Integer>> ans = new ArrayList<>();
boolean[] used;
int sum = 0;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
//为了将重复的数字都放到一起,所以先进行排序
Arrays.sort(candidates);
//加标志数组,用来辅助判断同层节点是否已经遍历
boolean[] flag = new boolean[candidates.length];
backTracking(candidates, target, 0, flag);
return lists;
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
used = new boolean[candidates.length];
// 加标志数组,用来辅助判断同层节点是否已经遍历
Arrays.fill(used, false);
// 为了将重复的数字都放到一起,所以先进行排序
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return ans;
}
public void backTracking(int[] arr, int target, int index, boolean[] flag) {
if (sum == target) {
lists.add(new ArrayList(deque));
return;
}
for (int i = index; i < arr.length && arr[i] + sum <= target; i++) {
//出现重复节点,同层的第一个节点已经被访问过,所以直接跳过
if (i > 0 && arr[i] == arr[i - 1] && !flag[i - 1]) {
continue;
}
flag[i] = true;
sum += arr[i];
deque.push(arr[i]);
//每个节点仅能选择一次,所以从下一位开始
backTracking(arr, target, i + 1, flag);
int temp = deque.pop();
flag[i] = false;
sum -= temp;
}
private void backTracking(int[] candidates, int target, int startIndex) {
if (sum == target) {
ans.add(new ArrayList(path));
}
for (int i = startIndex; i < candidates.length; i++) {
if (sum + candidates[i] > target) {
break;
}
// 出现重复节点,同层的第一个节点已经被访问过,所以直接跳过
if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) {
continue;
}
used[i] = true;
sum += candidates[i];
path.add(candidates[i]);
// 每个节点仅能选择一次,所以从下一位开始
backTracking(candidates, target, i + 1);
used[i] = false;
sum -= candidates[i];
path.removeLast();
}
}
}
```
**不使用标记数组**
```Java

View File

@ -331,7 +331,7 @@ var permute = function(nums) {
```
## TypeScript
### TypeScript
```typescript
function permute(nums: number[]): number[][] {

View File

@ -210,24 +210,54 @@ public:
```java
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int n = obstacleGrid.length, m = obstacleGrid[0].length;
int[][] dp = new int[n][m];
for (int i = 0; i < m; i++) {
if (obstacleGrid[0][i] == 1) break; //一旦遇到障碍,后续都到不了
dp[0][i] = 1;
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
//如果在起点或终点出现了障碍直接返回0
if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) {
return 0;
}
for (int i = 0; i < n; i++) {
if (obstacleGrid[i][0] == 1) break; ////一旦遇到障碍,后续都到不了
dp[i][0] = 1;
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {
dp[i][0] = 1;
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (obstacleGrid[i][j] == 1) continue;
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
dp[0][j] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = (obstacleGrid[i][j] == 0) ? dp[i - 1][j] + dp[i][j - 1] : 0;
}
}
return dp[n - 1][m - 1];
return dp[m - 1][n - 1];
}
}
```
```java
// 空间优化版本
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[] dp = new int[n];
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
dp[j] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 0; j < n; j++) {
if (obstacleGrid[i][j] == 1) {
dp[j] = 0;
} else if (j != 0) {
dp[j] += dp[j - 1];
}
}
}
return dp[n - 1];
}
}
```

View File

@ -213,22 +213,6 @@ public:
### Java
```Java
class Solution {
public int climbStairs(int n) {
// 跟斐波那契数列一样
if(n <= 2) return n;
int a = 1, b = 2, sum = 0;
for(int i = 3; i <= n; i++){
sum = a + b;
a = b;
b = sum;
}
return b;
}
}
```
```java
// 常规方式
@ -241,15 +225,22 @@ public int climbStairs(int n) {
}
return dp[n];
}
```
```Java
// 用变量记录代替数组
public int climbStairs(int n) {
int a = 0, b = 1, c = 0; // 默认需要1次
for (int i = 1; i <= n; i++) {
c = a + b; // f(i - 1) + f(n - 2)
a = b; // 记录上一轮的值
b = c; // 向后步进1个数
class Solution {
public int climbStairs(int n) {
if(n <= 2) return n;
int a = 1, b = 2, sum = 0;
for(int i = 3; i <= n; i++){
sum = a + b; // f(i - 1) + f(i - 2)
a = b; // 记录f(i - 1)即下一轮的f(i - 2)
b = sum; // 记录f(i)即下一轮的f(i - 1)
}
return b;
}
return c;
}
```

View File

@ -180,10 +180,6 @@ class Solution {
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
public List<List<Integer>> subsets(int[] nums) {
if (nums.length == 0){
result.add(new ArrayList<>());
return result;
}
subsetsHelper(nums, 0);
return result;
}

View File

@ -499,7 +499,7 @@ class solution:
if not cur_node.left and not cur_node.right:
if remain == 0:
result.append(path[:])
return
return
if cur_node.left:
path.append(cur_node.left.val)
@ -508,7 +508,7 @@ class solution:
if cur_node.right:
path.append(cur_node.right.val)
traversal(cur_node.right, remain-cur_node.left.val)
traversal(cur_node.right, remain-cur_node.right.val)
path.pop()
result, path = [], []

View File

@ -135,25 +135,22 @@ class Solution {
2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大
*/
public int candy(int[] ratings) {
int[] candyVec = new int[ratings.length];
int len = ratings.length;
int[] candyVec = new int[len];
candyVec[0] = 1;
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
candyVec[i] = candyVec[i - 1] + 1;
} else {
candyVec[i] = 1;
}
for (int i = 1; i < len; i++) {
candyVec[i] = (ratings[i] > ratings[i - 1]) ? candyVec[i - 1] + 1 : 1;
}
for (int i = ratings.length - 2; i >= 0; i--) {
for (int i = len - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candyVec[i] = Math.max(candyVec[i], candyVec[i + 1] + 1);
}
}
int ans = 0;
for (int s : candyVec) {
ans += s;
for (int num : candyVec) {
ans += num;
}
return ans;
}

View File

@ -144,3 +144,50 @@ public:
};
```
## 其他语言版本
### Java
```java
class Solution {
boolean[][] visited;
int[][] move = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public int numIslands(char[][] grid) {
int res = 0;
visited = new boolean[grid.length][grid[0].length];
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[0].length; j++) {
if(!visited[i][j] && grid[i][j] == '1') {
bfs(grid, i, j);
res++;
}
}
}
return res;
}
//将这片岛屿上的所有陆地都访问到
public void bfs(char[][] grid, int y, int x) {
Deque<int[]> queue = new ArrayDeque<>();
queue.offer(new int[]{y, x});
visited[y][x] = true;
while(!queue.isEmpty()) {
int[] cur = queue.poll();
int m = cur[0];
int n = cur[1];
for(int i = 0; i < 4; i++) {
int nexty = m + move[i][0];
int nextx = n + move[i][1];
if(nextx < 0 || nexty == grid.length || nexty < 0 || nextx == grid[0].length) continue;
if(!visited[nexty][nextx] && grid[nexty][nextx] == '1') {
queue.offer(new int[]{nexty, nextx});
visited[nexty][nextx] = true; //只要加入队列就标记为访问
}
}
}
}
}
```

View File

@ -260,6 +260,37 @@ class Solution {
}
}
}
// 上面剪枝 i <= 9 - (k - path.size()) + 1; 如果还是不清楚
// 也可以改为 if (path.size() > k) return; 执行效率上是一样的
class Solution {
LinkedList<Integer> path = new LinkedList<>();
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
build(k, n, 1, 0);
return ans;
}
private void build(int k, int n, int startIndex, int sum) {
if (sum > n) return;
if (path.size() > k) return;
if (sum == n && path.size() == k) {
ans.add(new ArrayList<>(path));
return;
}
for(int i = startIndex; i <= 9; i++) {
path.add(i);
sum += i;
build(k, n, i + 1, sum);
sum -= i;
path.removeLast();
}
}
}
```
其他方法

View File

@ -191,7 +191,7 @@ public:
vector<int> left = robTree(cur->left);
vector<int> right = robTree(cur->right);
// 偷cur那么就不能偷左右节点。
int val1 = cur->val + left[1] + right[1];
int val1 = cur->val + left[0] + right[0];
// 不偷cur那么可以偷也可以不偷左右节点则取较大的情况
int val2 = max(left[0], left[1]) + max(right[0], right[1]);
return {val2, val1};

View File

@ -269,18 +269,23 @@ class Solution:
**贪心**
```golang
func wiggleMaxLength(nums []int) int {
var count, preDiff, curDiff int //初始化默认为0
count = 1 // 初始化为1因为最小的序列是1个数
if len(nums) < 2 {
return count
n := len(nums)
if n < 2 {
return n
}
for i := 0; i < len(nums)-1; i++ {
curDiff = nums[i+1] - nums[i]
if (curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0) {
count++
ans := 1
prevDiff := nums[1] - nums[0]
if prevDiff != 0 {
ans = 2
}
for i := 2; i < n; i++ {
diff := nums[i] - nums[i-1]
if diff > 0 && prevDiff <= 0 || diff < 0 && prevDiff >= 0 {
ans++
prevDiff = diff
}
}
return count
return ans
}
```

View File

@ -137,29 +137,21 @@ public:
### Java
```java
/**
时间复杂度 : O(NlogN) 排序需要 O(NlogN) 的复杂度
空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间
*/
* 时间复杂度 : O(NlogN) 排序需要 O(NlogN) 的复杂度
* 空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间
*/
class Solution {
public int findMinArrowShots(int[][] points) {
if (points.length == 0) return 0;
//用x[0] - y[0] 会大于2147483647 造成整型溢出
Arrays.sort(points, (x, y) -> Integer.compare(x[0], y[0]));
//count = 1 因为最少需要一个箭来射击第一个气球
int count = 1;
//重叠气球的最小右边界
int leftmostRightBound = points[0][1];
// 根据气球直径的开始坐标从小到大排序
// 使用Integer内置比较方法不会溢出
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
int count = 1; // points 不为空至少需要一支箭
for (int i = 1; i < points.length; i++) {
//如果下一个气球的左边界大于最小右边界
for(int i = 1; i < points.length; i++){
if (points[i][0] > leftmostRightBound ) {
//增加一次射击
count++;
leftmostRightBound = points[i][1];
//不然就更新最小右边界
} else {
leftmostRightBound = Math.min(leftmostRightBound , points[i][1]);
if (points[i][0] > points[i - 1][1]) { // 气球i和气球i-1不挨着注意这里不是>=
count++; // 需要一支箭
} else { // 气球i和气球i-1挨着
points[i][1] = Math.min(points[i][1], points[i - 1][1]); // 更新重叠气球最小右边界
}
}
return count;

View File

@ -179,6 +179,25 @@ class Solution:
```
Go
```go
func islandPerimeter(grid [][]int) int {
m, n := len(grid), len(grid[0])
res := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
res += 4
// 上下左右四个方向
if i > 0 && grid[i-1][j] == 1 {res--} // 上边有岛屿
if i < m-1 && grid[i+1][j] == 1 {res--} // 下边有岛屿
if j > 0 && grid[i][j-1] == 1 {res--} // 左边有岛屿
if j < n-1 && grid[i][j+1] == 1 {res--} // 右边有岛屿
}
}
}
return res
}
```
JavaScript
```javascript

View File

@ -233,7 +233,7 @@ class Solution:
else: # 逐一处理节点
cur = stack.pop()
if pre: # 当前节点和前节点的值的差值
result = min(result, cur.val - pre.val)
result = min(result, abs(cur.val - pre.val))
pre = cur
cur = cur.right
return result

View File

@ -167,3 +167,111 @@ public:
};
```
# 其它语言版本
## Python
### BFS
```python
class Solution:
def __init__(self):
self.count = 0
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
# 与200.独立岛屿不同的是此题grid列表内是int
# BFS
if not grid: return 0
m, n = len(grid), len(grid[0])
visited = [[False for i in range(n)] for j in range(m)]
result = 0
for i in range(m):
for j in range(n):
if not visited[i][j] and grid[i][j] == 1:
# 每一个新岛屿
self.count = 0
print(f'{self.count}')
self.bfs(grid, visited, i, j)
result = max(result, self.count)
return result
def bfs(self, grid, visited, i, j):
self.count += 1
visited[i][j] = True
queue = collections.deque([(i, j)])
while queue:
x, y = queue.popleft()
for new_x, new_y in [(x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1)]:
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]) and not visited[new_x][new_y] and grid[new_x][new_y] == 1:
visited[new_x][new_y] = True
self.count += 1
queue.append((new_x, new_y))
```
### DFS
```python
class Solution:
def __init__(self):
self.count = 0
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
# DFS
if not grid: return 0
m, n = len(grid), len(grid[0])
visited = [[False for _ in range(n)] for _ in range(m)]
result = 0
for i in range(m):
for j in range(n):
if not visited[i][j] and grid[i][j] == 1:
self.count = 0
self.dfs(grid, visited, i, j)
result = max(result, self.count)
return result
def dfs(self, grid, visited, x, y):
if visited[x][y] or grid[x][y] == 0:
return
visited[x][y] = True
self.count += 1
for new_x, new_y in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]):
self.dfs(grid, visited, new_x, new_y)
```
## Java
这里使用深度优先搜索 DFS 来完成本道题目。我们使用 DFS 计算一个岛屿的面积,同时维护计算过的最大的岛屿面积。同时,为了避免对岛屿重复计算,我们在 DFS 的时候对岛屿进行 “淹没” 操作,即将岛屿所占的地方置为 0。
```java
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for(int i = 0;i < grid.length;i++){
for(int j = 0;j < grid[0].length;j++){
//每遇到一个岛屿就计算这个岛屿的面积同时”淹没“这个岛屿
if(grid[i][j] == 1){
//每次计算一个岛屿的面积都要与res比较维护最大的岛屿面积作为最后的答案
res = Math.max(res,dfs(grid,i,j));
}
}
}
return res;
}
public int dfs(int[][] grid,int i,int j){
//搜索边界ij超过grid的范围或者当前元素为0即当前所在的地方已经是海洋
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return 0;
//淹没土地,防止后续被重复计算
grid[i][j] = 0;
//递归的思路:要求当前土地(i,j)所在的岛屿的面积则等于1加上下左右相邻的土地的总面积
return 1 + dfs(grid,i - 1,j) +
dfs(grid,i + 1,j) +
dfs(grid,i,j + 1) +
dfs(grid,i,j - 1);
}
```

View File

@ -66,7 +66,7 @@
所以初始化代码为:
```
```CPP
vector<int> dp(cost.size());
dp[0] = cost[0];
dp[1] = cost[1];
@ -201,15 +201,32 @@ public:
### Java
```Java
// 方式一:第一步支付费用
class Solution {
public int minCostClimbingStairs(int[] cost) {
if (cost == null || cost.length == 0) {
return 0;
}
if (cost.length == 1) {
return cost[0];
int len = cost.length;
int[] dp = new int[len + 1];
// 从下标为 0 或下标为 1 的台阶开始因此支付费用为0
dp[0] = 0;
dp[1] = 0;
// 计算到达每一层台阶的最小费用
for (int i = 2; i <= len; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[len];
}
}
```
```Java
// 方式二:第一步不支付费用
class Solution {
public int minCostClimbingStairs(int[] cost) {
int[] dp = new int[cost.length];
dp[0] = cost[0];
dp[1] = cost[1];

View File

@ -296,5 +296,29 @@ public:
### Java
### Python
```
class Solution:
def __init__(self):
self.result = []
self.path = [0]
def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
if not graph: return []
self.dfs(graph, 0)
return self.result
def dfs(self, graph, root: int):
if root == len(graph) - 1: # 成功找到一条路径时
# ***Python的list是mutable类型***
# ***回溯中必须使用Deep Copy***
self.result.append(self.path[:])
return
for node in graph[root]: # 遍历节点n的所有后序节点
self.path.append(node)
self.dfs(graph, node)
self.path.pop() # 回溯
```
### Go

View File

@ -71,7 +71,7 @@
后序遍历代码如下:
```
```CPP
int traversal(TreeNode* cur) {
// 空节点,该节点有覆盖
@ -124,7 +124,7 @@ int traversal(TreeNode* cur) {
代码如下:
```
```CPP
// 空节点,该节点有覆盖
if (cur == NULL) return 2;
```
@ -143,7 +143,7 @@ if (cur == NULL) return 2;
代码如下:
```
```CPP
// 左右节点都有覆盖
if (left == 2 && right == 2) return 0;
```
@ -163,7 +163,7 @@ left == 2 && right == 0 左节点覆盖,右节点无覆盖
此时摄像头的数量要加一并且return 1代表中间节点放摄像头。
代码如下:
```
```CPP
if (left == 0 || right == 0) {
result++;
return 1;
@ -180,7 +180,7 @@ left == 1 && right == 1 左右节点都有摄像头
代码如下:
```
```CPP
if (left == 1 || right == 1) return 2;
```
@ -198,7 +198,7 @@ if (left == 1 || right == 1) return 2;
所以递归结束之后还要判断根节点如果没有覆盖result++,代码如下:
```
```CPP
int minCameraCover(TreeNode* root) {
result = 0;
if (traversal(root) == 0) { // root 无覆盖

View File

@ -170,6 +170,39 @@ class Solution:
## Go
```go
func sortByBits(arr []int) []int {
var tmp int
for i := 0; i < len(arr); i++ {
for j := i+1; j < len(arr); j++ {
// 冒泡排序的手法但是排序的规则从比大小变成了比位运算1的个数
if isCmp(arr[i], arr[j]) {
tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
}
}
}
return arr
}
func isCmp(a, b int) bool {
bitA := bitCount(a)
bitB := bitCount(b)
if bitA == bitB {
return a > b
} else {
return bitA > bitB
}
}
func bitCount(n int) int {
count := 0
for n != 0 {
n &= (n-1) // 清除最低位的1
count++
}
return count
}
```
## JavaScript

View File

@ -102,7 +102,7 @@
现在已经讲过了几种二叉树了,二叉树,二叉平衡树,完全二叉树,二叉搜索树,后面还会有平衡二叉搜索树。 那么一些同学难免会有混乱了,我针对如下三个问题,帮大家在捋顺一遍:
1. 平衡二叉搜索是不是二叉搜索树和平衡二叉树的结合?
1. 平衡二叉搜索是不是二叉搜索树和平衡二叉树的结合?
是的,是二叉搜索树和平衡二叉树的结合。