chore(i8n,learn): processed translations
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
15047f2d90
commit
e5c44a3ae5
@ -1,18 +1,34 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7b
|
||||
title: 将新元素添加到二叉搜索树
|
||||
title: Add a New Element to a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301618
|
||||
dashedName: add-a-new-element-to-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们已经了解了基础知识,让我们编写一个更复杂的方法。在此挑战中,我们将创建一个向二叉搜索树添加新值的方法。该方法应该被称为`add` ,它应该接受一个整数值来添加到树中。注意保持二叉搜索树的不变量:每个左子项中的值应小于或等于父值,并且每个右子项中的值应大于或等于父值。在这里,让我们这样做,以便我们的树不能容纳重复的值。如果我们尝试添加已存在的值,则该方法应返回`null` 。否则,如果添加成功,则应返回`undefined` 。提示:树是自然递归的数据结构!
|
||||
This series of challenges will introduce the tree data structure. Trees are an important and versatile data structure in computer science. Of course, their name comes from the fact that when visualized they look much like the trees we are familiar with in the natural world. A tree data structure begins with one node, typically referred to as the root, and from here branches out to additional nodes, each of which may have more child nodes, and so on and so forth. The data structure is usually visualized with the root node at the top; you can think of it as a natural tree flipped upside down.
|
||||
|
||||
First, let's describe some common terminology we will encounter with trees. The root node is the top of the tree. Data points in the tree are called nodes. Nodes with branches leading to other nodes are referred to as the parent of the node the branch leads to (the child). Other more complicated familial terms apply as you might expect. A subtree refers to all the descendants of a particular node, branches may be referred to as edges, and leaf nodes are nodes at the end of the tree that have no children. Finally, note that trees are inherently recursive data structures. That is, any children of a node are parents of their own subtree, and so on. The recursive nature of trees is important to understand when designing algorithms for common tree operations.
|
||||
|
||||
To begin, we will discuss a particular type of a tree, the binary tree. In fact, we will actually discuss a particular binary tree, a binary search tree. Let's describe what this means. While the tree data structure can have any number of branches at a single node, a binary tree can only have two branches for every node. Furthermore, a binary search tree is ordered with respect to the child subtrees, such that the value of each node in the left subtree is less than or equal to the value of the parent node, and the value of each node in the right subtree is greater than or equal to the value of the parent node. It's very helpful to visualize this relationship in order to understand it better:
|
||||
|
||||
<div style='width: 100%; display: flex; justify-content: center; align-items: center;'><img style='width: 100%; max-width: 350px; background-color: var(--gray-05);' src='https://user-images.githubusercontent.com/18563015/32136009-1e665d98-bbd6-11e7-9133-63184f9f9182.png'></div>
|
||||
|
||||
Now this ordered relationship is very easy to see. Note that every value to the left of 8, the root node, is less than 8, and every value to the right is greater than 8. Also notice that this relationship applies to each of the subtrees as well. For example, the first left child is a subtree. 3 is the parent node, and it has exactly two child nodes — by the rules governing binary search trees, we know without even looking that the left child of this node (and any of its children) will be less than 3, and the right child (and any of its children) will be greater than 3 (but also less than the structure's root value), and so on.
|
||||
|
||||
Binary search trees are very common and useful data structures because they provide logarithmic time in the average case for several common operations such as lookup, insertion, and deletion.
|
||||
|
||||
# --instructions--
|
||||
|
||||
We'll start simple. We've defined the skeleton of a binary search tree structure here in addition to a function to create nodes for our tree. Observe that each node may have a left and right value. These will be assigned child subtrees if they exist. In our binary search tree, you will create a method to add new values to our binary search tree. The method should be called `add` and it should accept an integer value to add to the tree. Take care to maintain the invariant of a binary search tree: the value in each left child should be less than or equal to the parent value, and the value in each right child should be greater than or equal to the parent value. Here, let's make it so our tree cannot hold duplicate values. If we try to add a value that already exists, the method should return `null`. Otherwise, if the addition is successful, `undefined` should be returned.
|
||||
|
||||
**Hint:** trees are naturally recursive data structures!
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +42,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`add`的方法。
|
||||
The binary search tree should have a method called `add`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +58,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
add方法根据二叉搜索树规则添加元素。
|
||||
The add method should add elements according to the binary search tree rules.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -71,7 +87,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
添加已存在的元素将返回`null`
|
||||
Adding an element that already exists should return `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -128,7 +144,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8252367417b2b2512c67
|
||||
title: 在链接列表中的特定索引处添加元素
|
||||
title: Add Elements at a Specific Index in a Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301619
|
||||
dashedName: add-elements-at-a-specific-index-in-a-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们创建一个addAt(index,element)方法,在给定的索引处添加一个元素。就像我们如何删除给定索引处的元素一样,我们需要在遍历链表时跟踪currentIndex。当currentIndex与给定索引匹配时,我们需要重新分配上一个节点的下一个属性以引用新添加的节点。并且新节点应该引用currentIndex中的下一个节点。回到康加线的例子,一个新人想加入这条线,但他想加入中间。你处于中间位置,所以你要把手从你前面的人身上移开。新人走过去,把手放在你曾经牵过手的那个人身上,现在你已经掌握了新人。说明创建addAt(index,element)方法,该方法在给定索引处添加元素。如果无法添加元素,则返回false。注意请记住检查给定索引是否为负数或者是否长于链接列表的长度。
|
||||
Let's create a addAt(index,element) method that adds an element at a given index. Just like how we remove elements at a given index, we need to keep track of the currentIndex as we traverse the linked list. When the currentIndex matches the given index, we would need to reassign the previous node's next property to reference the new added node. And the new node should reference the next node in the currentIndex. Returning to the conga line example, a new person wants to join the line, but he wants to join in the middle. You are in the middle of the line, so you take your hands off of the person ahead of you. The new person walks over and puts his hands on the person you once had hands on, and you now have your hands on the new person.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Create an `addAt(index,element)` method that adds an element at a given index. Return false if an element could not be added. **Note:** Remember to check if the given index is a negative or is longer than the length of the linked list.
|
||||
|
||||
# --hints--
|
||||
|
||||
当给定索引为0时, `addAt`方法应重新分配`head`到新节点。
|
||||
Your `addAt` method should reassign `head` to the new node when the given index is 0.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
对于添加到链接列表的每个新节点, `addAt`方法应该将链表的长度增加一。
|
||||
Your `addAt` method should increase the length of the linked list by one for each new node added to the linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -40,7 +44,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果无法添加节点,则`addAt`方法应返回`false` 。
|
||||
Your `addAt` method should return `false` if a node was unable to be added.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,48 +1,50 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c77
|
||||
title: 邻接名单
|
||||
title: Adjacency List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301620
|
||||
dashedName: adjacency-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
图表可以以不同方式表示。这里我们描述一种方法,称为<dfn>邻接列表</dfn> 。邻接列表本质上是项目符号列表,其中左侧是节点,右侧列出它所连接的所有其他节点。下面是邻接列表的表示。
|
||||
Graphs can be represented in different ways. Here we describe one way, which is called an <dfn>adjacency list</dfn>. An adjacency list is essentially a bulleted list where the left side is the node and the right side lists all the other nodes it's connected to. Below is a representation of an adjacency list.
|
||||
|
||||
> Node1:Node2,Node3
|
||||
> Node2:Node1
|
||||
> Node3:Node1
|
||||
<blockquote>Node1: Node2, Node3<br>Node2: Node1<br>Node3: Node1</blockquote>
|
||||
|
||||
以上是无向图,因为`Node1`连接到`Node2`和`Node3` ,并且该信息与`Node2`和`Node3`显示的连接一致。有向图的邻接列表意味着列表的每一行都显示方向。如果指示上述内容,那么`Node2: Node1`将意味着有向边缘从`Node2`指向`Node1` 。我们可以将上面的无向图表示为邻接列表,方法是将其放在JavaScript对象中。
|
||||
Above is an undirected graph because `Node1` is connected to `Node2` and `Node3`, and that information is consistent with the connections `Node2` and `Node3` show. An adjacency list for a directed graph would mean each row of the list shows direction. If the above was directed, then `Node2: Node1` would mean there the directed edge is pointing from `Node2` towards `Node1`. We can represent the undirected graph above as an adjacency list by putting it within a JavaScript object.
|
||||
|
||||
> var undirectedG = {
|
||||
> 节点1:\[“Node2”,“Node3”],
|
||||
> Node2:\[“Node1”],
|
||||
> Node3:\[“Node1”]
|
||||
> };
|
||||
```js
|
||||
var undirectedG = {
|
||||
Node1: ["Node2", "Node3"],
|
||||
Node2: ["Node1"],
|
||||
Node3: ["Node1"]
|
||||
};
|
||||
```
|
||||
|
||||
这也可以更简单地表示为一个数组,其中节点只有数字而不是字符串标签。
|
||||
This can also be more simply represented as an array where the nodes just have numbers rather than string labels.
|
||||
|
||||
> var undirectedGArr = \[
|
||||
> \[1,2],#Node1
|
||||
> \[0],#Node2
|
||||
> \[0] #Node3
|
||||
> ]。
|
||||
```js
|
||||
var undirectedGArr = [
|
||||
[1, 2], // Node1
|
||||
[0], // Node2
|
||||
[0] // Node3
|
||||
];
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
创建一个社交网络作为无向图,其中有4个节点/人名为`James` , `Jill` , `Jenny`和`Jeff` 。詹姆斯和杰夫,吉尔和珍妮以及杰夫和珍妮之间存在边缘/关系。
|
||||
Create a social network as an undirected graph with 4 nodes/people named `James`, `Jill`, `Jenny`, and `Jeff`. There are edges/relationships between James and Jeff, Jill and Jenny, and Jeff and Jenny.
|
||||
|
||||
# --hints--
|
||||
|
||||
`undirectedAdjList`应该只包含四个节点。
|
||||
`undirectedAdjList` should only contain four nodes.
|
||||
|
||||
```js
|
||||
assert(Object.keys(undirectedAdjList).length === 4);
|
||||
```
|
||||
|
||||
`Jeff`和`James`之间应该有优势。
|
||||
There should be an edge between `Jeff` and `James`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -51,7 +53,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`Jill`和`Jenny`之间应该有一个优势。
|
||||
There should be an edge between `Jill` and `Jenny`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -60,7 +62,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`Jeff`和`Jenny`之间应该有优势。
|
||||
There should be an edge between `Jeff` and `Jenny`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,56 +1,54 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c78
|
||||
title: 邻接矩阵
|
||||
title: Adjacency Matrix
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301621
|
||||
dashedName: adjacency-matrix
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
表示图形的另一种方法是将其置于<dfn>邻接矩阵中</dfn> 。 <dfn>邻接矩阵</dfn>是二维(2D)阵列,其中每个嵌套数组具有与外部数组相同数量的元素。换句话说,它是数字的矩阵或网格,其中数字代表边缘。零意味着没有边缘或关系。
|
||||
Another way to represent a graph is to put it in an <dfn>adjacency matrix</dfn>. An <dfn>adjacency matrix</dfn> is a two-dimensional (2D) array where each nested array has the same number of elements as the outer array. In other words, it is a matrix or grid of numbers, where the numbers represent the edges.
|
||||
|
||||
> 1 2 3
|
||||
>
|
||||
> * * *
|
||||
>
|
||||
> 1 | 0 1 1
|
||||
> 2 | 1 0 0
|
||||
> 3 | 1 0 0
|
||||
**Note**: The numbers to the top and left of the matrix are just labels for the nodes. Inside the matrix, ones mean there exists an edge between the vertices (nodes) representing the row and column. Finally, zeros mean there is no edge or relationship.
|
||||
|
||||
上面是一个非常简单的无向图,其中有三个节点,第一个节点连接到第二个和第三个节点。 **注意** :矩阵顶部和左侧的数字只是节点的标签。下面是同一件事的JavaScript实现。
|
||||
<pre>
|
||||
1 2 3
|
||||
\------
|
||||
1 | 0 1 1
|
||||
2 | 1 0 0
|
||||
3 | 1 0 0
|
||||
</pre>
|
||||
|
||||
> var adjMat = \[
|
||||
> \[0,1,1],
|
||||
> \[1,0,0],
|
||||
> \[1,0,0]
|
||||
> ]。
|
||||
Above is a very simple, undirected graph where you have three nodes, where the first node is connected to the second and third node. Below is a JavaScript implementation of the same thing.
|
||||
|
||||
与邻接列表不同,矩阵的每个“行”必须具有与图中的节点相同数量的元素。这里我们有一个三乘三矩阵,这意味着我们的图中有三个节点。有向图看起来很相似。下面是第一节点具有指向第二节点的边缘,然后第二节点具有指向第三节点的边缘的图。
|
||||
```js
|
||||
var adjMat = [
|
||||
[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 0, 0]
|
||||
];
|
||||
```
|
||||
|
||||
> var adjMatDirected = \[
|
||||
> \[0,1,0],
|
||||
> \[0,0,1],
|
||||
> \[0,0,0]
|
||||
> ]。
|
||||
Unlike an adjacency list, each "row" of the matrix has to have the same number of elements as nodes in the graph. Here we have a three by three matrix, which means we have three nodes in our graph. A directed graph would look similar. Below is a graph where the first node has an edge pointing toward the second node, and then the second node has an edge pointing to the third node.
|
||||
|
||||
图形的边缘也可以有权
|
||||
```js
|
||||
var adjMatDirected = [
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
[0, 0, 0]
|
||||
];
|
||||
```
|
||||
|
||||
<dfn>重</dfn>
|
||||
|
||||
。到目前为止,我们有
|
||||
|
||||
<dfn>未加权的</dfn>
|
||||
|
||||
边缘,只有存在和缺少边是二进制( `0`或`1` )。根据您的应用,您可以拥有不同的重量。
|
||||
Graphs can also have <dfn>weights</dfn> on their edges. So far, we have <dfn>unweighted</dfn> edges where just the presence and lack of edge is binary (`0` or `1`). You can have different weights depending on your application.
|
||||
|
||||
# --instructions--
|
||||
|
||||
创建具有五个节点的无向图的邻接矩阵。该矩阵应该是多维数组。这五个节点在第一和第四节点,第一和第三节点,第三和第五节点以及第四和第五节点之间具有关系。所有边缘权重都是一个。
|
||||
Create an adjacency matrix of an undirected graph with five nodes. This matrix should be in a multi-dimensional array. These five nodes have relationships between the first and fourth node, the first and third node, the third and fifth node, and the fourth and fifth node. All edge weights are one.
|
||||
|
||||
# --hints--
|
||||
|
||||
`undirectedAdjList`应该只包含五个节点。
|
||||
`undirectedAdjList` should only contain five nodes.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -65,25 +63,25 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
第一个和第四个节点之间应该有一条边。
|
||||
There should be an edge between the first and fourth node.
|
||||
|
||||
```js
|
||||
assert(adjMatUndirected[0][3] === 1 && adjMatUndirected[3][0] === 1);
|
||||
```
|
||||
|
||||
第一个和第三个节点之间应该有一条边。
|
||||
There should be an edge between the first and third node.
|
||||
|
||||
```js
|
||||
assert(adjMatUndirected[0][2] === 1 && adjMatUndirected[2][0] === 1);
|
||||
```
|
||||
|
||||
第三个和第五个节点之间应该有一条边。
|
||||
There should be an edge between the third and fifth node.
|
||||
|
||||
```js
|
||||
assert(adjMatUndirected[2][4] === 1 && adjMatUndirected[4][2] === 1);
|
||||
```
|
||||
|
||||
第四个和第五个节点之间应该有一条边。
|
||||
There should be an edge between the fourth and fifth node.
|
||||
|
||||
```js
|
||||
assert(adjMatUndirected[3][4] === 1 && adjMatUndirected[4][3] === 1);
|
||||
|
@ -1,22 +1,38 @@
|
||||
---
|
||||
id: 587d825c367417b2b2512c90
|
||||
title: 广度优先搜索
|
||||
title: Breadth-First Search
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301622
|
||||
dashedName: breadth-first-search
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
到目前为止,我们已经学会了创建图表表示的不同方法。现在怎么办?一个自然的问题是图中任何两个节点之间的距离是多少?输入<dfn>图遍历算法</dfn> 。 <dfn>遍历算法</dfn>是遍历或访问图中节点的算法。一种遍历算法是广度优先搜索算法。该算法从一个节点开始,首先访问一个边缘的所有邻居,然后继续访问它们的每个邻居。在视觉上,这就是算法正在做的事情。 要实现此算法,您需要输入图形结构和要启动的节点。首先,您需要了解距起始节点的距离。这个你想要开始你所有的距离最初一些大的数字,如`Infinity` 。这为从起始节点无法访问节点的情况提供了参考。接下来,您将要从开始节点转到其邻居。这些邻居是一个边缘,此时你应该添加一个距离单位到你要跟踪的距离。最后,有助于实现广度优先搜索算法的重要数据结构是队列。这是一个数组,您可以在其中添加元素到一端并从另一端删除元素。这也称为<dfn>FIFO</dfn>或<dfn>先进先出</dfn>数据结构。
|
||||
So far, we've learned different ways of creating representations of graphs. What now? One natural question to have is what are the distances between any two nodes in the graph? Enter <dfn>graph traversal algorithms</dfn>.
|
||||
|
||||
<dfn>Traversal algorithms</dfn> are algorithms to traverse or visit nodes in a graph. One type of traversal algorithm is the breadth-first search algorithm.
|
||||
|
||||
This algorithm starts at one node and visits all its neighbors that are one edge away. It then goes on to visit each of their neighbors and so on until all nodes have been reached.
|
||||
|
||||
An important data structure that will help implement the breadth-first search algorithm is the queue. This is an array where you can add elements to one end and remove elements from the other end. This is also known as a <dfn>FIFO</dfn> or <dfn>First-In-First-Out</dfn> data structure.
|
||||
|
||||
Visually, this is what the algorithm is doing. 
|
||||
|
||||
The grey shading represents a node getting added into the queue and the black shading represents a node getting removed from the queue. See how every time a node gets removed from the queue (node turns black), all their neighbors get added into the queue (node turns grey).
|
||||
|
||||
To implement this algorithm, you'll need to input a graph structure and a node you want to start at.
|
||||
|
||||
First, you'll want to be aware of the distances from, or number of edges away from, the start node. You'll want to start all your distances with some large number, like `Infinity`. This prevents counting issues for when a node may not be reachable from your start node. Next, you'll want to go from the start node to its neighbors. These neighbors are one edge away and at this point you should add one unit of distance to the distances you're keeping track of.
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写一个函数`bfs()` ,它将邻接矩阵图(二维数组)和节点标签根作为参数。节点标签只是`0`到`n - 1`之间节点的整数值,其中`n`是图中节点的总数。您的函数将输出JavaScript对象键值对与节点及其与根的距离。如果无法到达节点,则其距离应为`Infinity` 。
|
||||
Write a function `bfs()` that takes an adjacency matrix graph (a two-dimensional array) and a node label root as parameters. The node label will just be the integer value of the node between `0` and `n - 1`, where `n` is the total number of nodes in the graph.
|
||||
|
||||
Your function will output a JavaScript object key-value pairs with the node and its distance from the root. If the node could not be reached, it should have a distance of `Infinity`.
|
||||
|
||||
# --hints--
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` ,起始节点为`1`应该返回`{0: 1, 1: 0, 2: 1, 3: 2}`
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` with a start node of `1` should return `{0: 1, 1: 0, 2: 1, 3: 2}`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -33,7 +49,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` ,起始节点为`1`应该返回`{0: 1, 1: 0, 2: 1, 3: Infinity}`
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` with a start node of `1` should return `{0: 1, 1: 0, 2: 1, 3: Infinity}`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -50,7 +66,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` ,起始节点为`0`应该返回`{0: 0, 1: 1, 2: 2, 3: 3}`
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` with a start node of `0` should return `{0: 0, 1: 1, 2: 2, 3: 3}`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -67,7 +83,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
起始节点为`0`的输入图`[[0, 1], [1, 0]]`应返回`{0: 0, 1: 1}`
|
||||
The input graph `[[0, 1], [1, 0]]` with a start node of `0` should return `{0: 0, 1: 1}`
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7c
|
||||
title: 检查二进制搜索树中是否存在元素
|
||||
title: Check if an Element is Present in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301623
|
||||
dashedName: check-if-an-element-is-present-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们对二进制搜索树有了一般意义,让我们更详细地讨论它。二进制搜索树为平均情况下的查找,插入和删除的常见操作提供对数时间,并且在最坏情况下提供线性时间。为什么是这样?这些基本操作中的每一个都要求我们在树中找到一个项目(或者在插入的情况下找到它应该去的地方),并且由于每个父节点处的树结构,我们向左或向右分支并且有效地排除了一半的大小剩下的树。这使得搜索与树中节点数的对数成比例,这在平均情况下为这些操作创建对数时间。好的,但最坏的情况呢?那么,可考虑从以下值建构一棵树,将它们从左至右: `10` , `12` , `17` , `25` 。根据我们的规则二叉搜索树,我们将增加`12`到右侧`10` , `17` ,以这样的权利,以及`25`到这一权利。现在我们的树类似于一个链表,并且遍历它以找到`25`将要求我们以线性方式遍历所有项目。因此,在最坏的情况下,线性时间。这里的问题是树是不平衡的。我们将更多地了解这在以下挑战中意味着什么。说明:在此挑战中,我们将为树创建一个实用程序。编写一个方法`isPresent` ,它接受一个整数值作为输入,并在二叉搜索树中返回该值是否存在的布尔值。
|
||||
Now that we have a general sense of what a binary search tree is let's talk about it in a little more detail. Binary search trees provide logarithmic time for the common operations of lookup, insertion, and deletion in the average case, and linear time in the worst case. Why is this? Each of those basic operations requires us to find an item in the tree (or in the case of insertion to find where it should go) and because of the tree structure at each parent node we are branching left or right and effectively excluding half the size of the remaining tree. This makes the search proportional to the logarithm of the number of nodes in the tree, which creates logarithmic time for these operations in the average case. Ok, but what about the worst case? Well, consider constructing a tree from the following values, adding them left to right: `10`, `12`, `17`, `25`. Following our rules for a binary search tree, we will add `12` to the right of `10`, `17` to the right of this, and `25` to the right of this. Now our tree resembles a linked list and traversing it to find `25` would require us to traverse all the items in linear fashion. Hence, linear time in the worst case. The problem here is that the tree is unbalanced. We'll look a little more into what this means in the following challenges.
|
||||
|
||||
# --instructions--
|
||||
|
||||
In this challenge, we will create a utility for our tree. Write a method `isPresent` which takes an integer value as input and returns a boolean value for the presence or absence of that value in the binary search tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`isPresent`的方法。
|
||||
The binary search tree should have a method called `isPresent`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`isPresent`方法正确检查添加到树中的元素是否存在。
|
||||
The `isPresent` method should correctly check for the presence or absence of elements added to the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -70,7 +74,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`isPresent`处理树为空的情况。
|
||||
`isPresent` should handle cases where the tree is empty.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -141,7 +145,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -89,7 +89,7 @@ function BinarySearchTree() {
|
||||
}
|
||||
function isBinarySearchTree(tree) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,42 +1,62 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c75
|
||||
title: 创建循环队列
|
||||
title: Create a Circular Queue
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301625
|
||||
dashedName: create-a-circular-queue
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在此挑战中,您将创建一个循环队列。循环队列基本上是一个写入集合末尾的队列,然后开始在集合开头写自己。这种类型的数据结构在某些情况下具有一些有用的应用。例如,循环队列可用于流媒体。队列填满后,新媒体数据就会开始覆盖旧数据。说明这个概念的一个好方法是使用数组:
|
||||
In this challenge you will be creating a Circular Queue. A circular queue is a queue that writes to the end of a collection then begins overwriting itself at the beginning of the collection. This type of data structure is useful in certain situations. For example, a circular queue can be used for streaming media. Once the queue is full, new media data will overwrite old data.
|
||||
|
||||
> \[1,2,3,4,5]
|
||||
> ^读@ 0
|
||||
> ^写@ 0
|
||||
A good way to illustrate this concept is with an array of length `5`:
|
||||
|
||||
这里的读写都在`0` 。现在队列获得3个新记录`a` , `b`和`c` 。我们的队列现在看起来像:
|
||||
```js
|
||||
[null, null, null, null, null]
|
||||
^Read @ 0
|
||||
^Write @ 0
|
||||
```
|
||||
|
||||
> \[a,b,c,4,5]
|
||||
> ^读@ 0
|
||||
> ^写@ 3
|
||||
Here the read and write are both at position `0`. Now the queue gets 3 new records `a`, `b`, and `c`. Our queue now looks like:
|
||||
|
||||
当读头读取时,它可以删除值或保留它们:
|
||||
```js
|
||||
[a, b, c, null, null]
|
||||
^Read @ 0
|
||||
^Write @ 3
|
||||
```
|
||||
|
||||
> \[null,null,null,4,5]
|
||||
> ^阅读@ 3
|
||||
> ^写@ 3
|
||||
As the read head reads, it can remove values or keep them:
|
||||
|
||||
一旦写入到达数组的末尾,它就会循环回到开头:
|
||||
```js
|
||||
[null, null, null, null, null]
|
||||
^Read @ 3
|
||||
^Write @ 3
|
||||
```
|
||||
|
||||
> \[f,null,null,d,e]
|
||||
> ^阅读@ 3
|
||||
> ^写@ 1
|
||||
Now we write the values `d`, `e`, and `f` to the queue. Once the write reaches the end of the array it loops back to the beginning:
|
||||
|
||||
这种方法需要恒定的内存量,但允许处理更大尺寸的文件。说明:在此挑战中,我们将实现循环队列。循环队列应提供`enqueue`和`dequeue`方法,允许您读取和写入队列。类本身也应该接受一个整数,您可以使用该整数在创建队列时指定队列的大小。我们已经在代码编辑器中为您编写了此类的起始版本。将项目排入队列时,写入指针应向前推进,并在到达队列末尾时循环回到开头。同样,当您使项目出列时,读指针应向前推进。不应允许写指针移过读指针(我们的类不会让你覆盖你还没有读过的数据),并且读指针不能超过你写的数据。此外,如果成功,则`enqueue`方法应返回您入`enqueue`的项,否则返回`null` 。类似地,当你使一个项目出列时,它应该被返回,如果你不能出列,你应该返回`null` 。
|
||||
```js
|
||||
[f, null, null, d, e]
|
||||
^Read @ 3
|
||||
^Write @ 1
|
||||
```
|
||||
|
||||
This approach requires a constant amount of memory but allows files of a much larger size to be processed.
|
||||
|
||||
# --instructions--
|
||||
|
||||
In this challenge we will implement a circular queue. The circular queue should provide `enqueue` and `dequeue` methods which allow you to read from and write to the queue. The class itself should also accept an integer argument which you can use to specify the size of the queue when created. We've written the starting version of this class for you in the code editor.
|
||||
|
||||
When you enqueue items to the queue, the write pointer should advance forward and loop back to the beginning once it reaches the end of the queue. The `enqueue` method should return the item you enqueued if it is successful; otherwise it will return `null`.
|
||||
|
||||
Likewise, the read pointer should advance forward as you dequeue items. When you dequeue an item, that item should be returned. If you cannot dequeue an item, you should return `null`.
|
||||
|
||||
The write pointer should not be allowed to move past the read pointer (our class won't let you overwrite data you haven't read yet) and the read pointer should not be able to advance past data you have written.
|
||||
|
||||
# --hints--
|
||||
|
||||
`enqueue`方法将项添加到循环队列。
|
||||
The `enqueue` method should add items to the circular queue.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -51,7 +71,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您不能通过读指针将项排入队列。
|
||||
You should not enqueue items past the read pointer.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -69,7 +89,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`dequeue`方法使队列中的项目出列。
|
||||
The `dequeue` method should dequeue items from the queue.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -85,7 +105,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
项目出列后,其队列中的位置应重置为`null` 。
|
||||
After an item is dequeued, its position in the queue should be reset to `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -102,7 +122,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
尝试通过写指针出列队列返回`null`并且不会使写指针前进。
|
||||
Trying to dequeue past the write pointer should return `null` and does not advance the write pointer.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,22 +1,26 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c87
|
||||
title: 创建双向链接列表
|
||||
title: Create a Doubly Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301626
|
||||
dashedName: create-a-doubly-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
到目前为止,我们创建的所有链接列表都是单链表。在这里,我们将创建一个<dfn>双向链表</dfn> 。顾名思义,双向链表中的节点引用了列表中的下一个和上一个节点。这允许我们在两个方向上遍历列表,但它还需要使用更多内存,因为每个节点必须包含对列表中前一个节点的附加引用。
|
||||
All of the linked lists we've created so far are singly linked lists. Here, we'll create a <dfn>doubly linked list</dfn>. As the name implies, nodes in a doubly linked list have references to the next and previous node in the list.
|
||||
|
||||
This allows us to traverse the list in both directions but it also requires more memory to be used because every node must contain an additional reference to the previous node in the list.
|
||||
|
||||
# --instructions--
|
||||
|
||||
我们提供了一个`Node`对象并启动了我们的`DoublyLinkedList` 。让我们将两个方法添加到名为`add` and `remove`双向链表`remove` 。 `add`方法应该将给定元素添加到列表中,而`remove`方法应该删除列表中所有出现的给定元素。编写这些方法时要小心处理任何可能的边缘情况,例如删除第一个或最后一个元素。此外,删除空列表中的任何项应返回`null` 。
|
||||
We've provided a `Node` object and started our `DoublyLinkedList`. Let's add two methods to our doubly linked list called `add` and `remove`. The `add` method should add the given element to the list while the `remove` method should remove all occurrences of a given element in the list.
|
||||
|
||||
Be careful to handle any possible edge cases when writing these methods, such as deletions for the first or last element. Also, removing any item on an empty list should return `null`.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在DoublyLinkedList数据结构。
|
||||
The DoublyLinkedList data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -30,7 +34,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
DoublyLinkedList有一个名为add的方法。
|
||||
The DoublyLinkedList should have a method called add.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -47,7 +51,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
DoublyLinkedList有一个名为remove的方法。
|
||||
The DoublyLinkedList should have a method called remove.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -64,7 +68,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
从空列表中删除项目将返回null。
|
||||
Removing an item from an empty list should return null.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -78,7 +82,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
add方法将项添加到列表中。
|
||||
The add method should add items to the list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -95,7 +99,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
每个节点都跟踪前一个节点。
|
||||
Each node should keep track of the previous node.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -112,7 +116,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
可以从列表中删除第一个项目。
|
||||
The first item should be removable from the list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -130,7 +134,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
最后一项可以从列表中删除。
|
||||
The last item should be removable from the list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -156,7 +160,7 @@ assert(
|
||||
DoublyLinkedList.prototype = Object.assign(
|
||||
DoublyLinkedList.prototype,
|
||||
{
|
||||
|
||||
|
||||
print() {
|
||||
if (this.head == null) {
|
||||
return null;
|
||||
@ -200,7 +204,7 @@ var DoublyLinkedList = function() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,18 +1,28 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8e
|
||||
title: 创建一个哈希表
|
||||
title: Create a Hash Table
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301627
|
||||
dashedName: create-a-hash-table
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在这个挑战中,我们将学习哈希表。哈希表用于实现关联数组或键值对的映射,就像我们刚刚研究的对象和地图一样。例如,JavaScript对象可以实现为哈希表(其实际实现将取决于它运行的环境)。哈希表的工作方式是它接受一个键输入并以确定的方式将此键散列到某个数值。然后将该数值用作存储相关值的实际键。然后,如果您尝试再次访问相同的密钥,则散列函数将处理密钥,返回相同的数字结果,然后将用于查找关联的值。这平均提供非常有效的O(1)查找时间。散列表可以实现为具有散列函数的数组,从而生成指定范围内的数组索引。在这种方法中,数组大小的选择很重要,散列函数也是如此。例如,如果散列函数为两个不同的键生成相同的值,该怎么办?这称为碰撞。处理冲突的一种方法是仅将两个键值对存储在该索引处。然后,在查找其中任何一个时,您将不得不遍历项目桶以找到您要查找的密钥。良好的散列函数可最大限度地减少冲突,从而保持有效的搜索时间。在这里,我们不会关注散列或散列表实现的细节,我们将尝试大致了解它们的工作原理。说明:让我们创建哈希表的基本功能。我们已经创建了一个天真的散列函数供您使用。您可以将字符串值传递给函数哈希,它将返回一个哈希值,您可以将其用作存储键。在this.collection对象中根据此散列值存储项目。创建这三种方法:添加,删除和查找。第一个应该接受一个键值对来添加到哈希表。第二个应该在传递密钥时删除键值对。第三个应该接受一个键并返回相关的值,如果该键不存在则返回null。请务必编写代码以解决冲突!
|
||||
In this challenge we will learn about hash tables. A Hash table is used to implement associative arrays, or mappings of key-value pairs, like the objects and Maps we have just been studying. A JavaScript object could be implemented as a hash table, for instance (its actual implementation will depend on the environment it's running in). The way a hash table works is that it takes a key input and hashes this key in a deterministic way to some numerical value. This numerical value is then used as the actual key the associated value is stored by. Then, if you try to access the same key again, the hashing function will process the key, return the same numerical result, which will then be used to look up the associated value. This provides very efficient O(1) lookup time on average.
|
||||
|
||||
Hash tables can be implemented as arrays with hash functions producing array indices within a specified range. In this method, the choice of the array size is important, as is the hashing function. For instance, what if the hashing function produces the same value for two different keys? This is called a collision. One way to handle collisions is to just store both key-value pairs at that index. Then, upon lookup of either, you would have to iterate through the bucket of items to find the key you are looking for. A good hashing function will minimize collisions to maintain efficient search time.
|
||||
|
||||
Here, we won't be concerned with the details of hashing or hash table implementation, we will just try to get a general sense of how they work.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Let's create the basic functionality of a hash table. We've created a naive hashing function for you to use. You can pass a string value to the function `hash` and it will return a hashed value you can use as a key for storage. Store items based on this hashed value in the `this.collection` object. Create these three methods: `add`, `remove`, and `lookup`. The first should accept a key value pair to add to the hash table. The second should remove a key-value pair when passed a key. The third should accept a key and return the associated value or `null` if the key is not present.
|
||||
|
||||
Be sure to write your code to account for collisions!
|
||||
|
||||
# --hints--
|
||||
|
||||
存在HashTable数据结构。
|
||||
The HashTable data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +36,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
HashTable有一个add方法。
|
||||
The HashTable should have an add method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -40,7 +50,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
HashTable有一个删除方法。
|
||||
The HashTable should have a remove method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -54,7 +64,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
HashTable有一个查找方法。
|
||||
The HashTable should have a lookup method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -68,7 +78,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
add方法添加键值对,lookup方法返回与给定键关联的值。
|
||||
The add method should add key value pairs and the lookup method should return the values associated with a given key.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -83,32 +93,25 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
remove方法接受一个键作为输入,并删除关联的键值对。
|
||||
The remove method should accept a key as input and should remove the associated key value pair.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = false;
|
||||
var hashValue = hash('key');
|
||||
if (typeof HashTable !== 'undefined') {
|
||||
test = new HashTable();
|
||||
}
|
||||
test.add = addMethodSolution;
|
||||
test.add('key', 'value');
|
||||
test.remove('key');
|
||||
test.lookup = function (key) {
|
||||
var theHash = hash(key);
|
||||
if (this.collection.hasOwnProperty(theHash)[key]) {
|
||||
return this.collection[theHash][key];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
var lookup = test.lookup('key');
|
||||
test.lookup = null;
|
||||
return lookup === null;
|
||||
return !test.collection.hasOwnProperty(hashValue);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
使用哈希函数添加项目。
|
||||
Items should be added using the hash function.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -126,7 +129,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
哈希表处理冲突。
|
||||
The hash table should handle collisions.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -187,7 +190,7 @@ var hash = string => {
|
||||
var HashTable = function() {
|
||||
this.collection = {};
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,22 +1,32 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c62
|
||||
title: 创建链接列表类
|
||||
title: Create a Linked List Class
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301628
|
||||
dashedName: create-a-linked-list-class
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们创建一个`linked list`类。每个链接列表都应该从一些基本属性开始: `head` (列表中的第一项)和`length` (列表中的项目数)。有时您会看到链接列表的实现,其中包含列表的最后一个元素的`tail` ,但是现在我们将坚持使用这两个元素。每当我们向链表添加元素时,我们的`length`属性应该加1。我们想要一种方法将项添加到链表中,因此我们要创建的第一种方法是`add`方法。如果我们的列表为空,那么向链表添加一个元素就足够了:我们只是将该元素包装在`Node`类中,然后将该节点分配给链表的`head` 。但是如果我们的名单已经有一个或多个成员呢?我们如何在列表中添加元素?回想一下,链表中的每个节点都有一个`next`属性。要将节点添加到列表,请在列表中找到最后一个节点,并将该节点的最后`next`属性指向新节点。 (提示:当节点的`next`属性为`null`时,您知道已到达链表的末尾。)
|
||||
Let's create a `linked list` class. Every linked list should start out with a few basic properties: a `head` (the first item in your list) and a `length` (number of items in your list). Sometimes you'll see implementations of linked lists that incorporate a `tail` for the last element of the list, but for now we'll just stick with these two. Whenever we add an element to the linked list, our `length` property should be incremented by one.
|
||||
|
||||
We'll want to have a way to add items to our linked list, so the first method we'll want to create is the `add` method.
|
||||
|
||||
If our list is empty, adding an element to our linked list is straightforward enough: we just wrap that element in a `Node` class, and we assign that node to the `head` of our linked list.
|
||||
|
||||
But what if our list already has one or more members? How do we add an element to the list? Recall that each node in a linked list has a `next` property. To add a node to the list, find the last node in the list, and point that last node's `next` property at our new node. (Hint: you know you've reached the end of a linked list when a node's `next` property is `null`.)
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写一个add方法,将您推送到链接列表的第一个节点分配给`head` ;之后,每当添加一个节点时,每个节点都应该由前一个节点的`next`属性引用。注意每次将元素添加到链接列表时,列表的`length`应增加1。
|
||||
Write an add method that assigns the first node you push to the linked list to the `head`; after that, whenever adding a node, every node should be referenced by the previous node's `next` property.
|
||||
|
||||
Note
|
||||
|
||||
Your list's `length` should increase by one every time an element is added to the linked list.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`LinkedList`类应该有一个`add`方法。
|
||||
Your `LinkedList` class should have a `add` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -27,7 +37,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`LinkedList`类应该为添加的第一个节点分配`head` 。
|
||||
Your `LinkedList` class should assign `head` to the first node added.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -39,7 +49,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`LinkedList`类中的上一个`node`应该引用创建的最新节点。
|
||||
The previous `node` in your `LinkedList` class should have reference to the newest node created.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -52,7 +62,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`LinkedList`类的`size`应该等于`LinkedList`的节点数量。
|
||||
The `size` of your `LinkedList` class should equal the amount of nodes in the linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,40 +1,32 @@
|
||||
---
|
||||
id: 8d5823c8c441eddfaeb5bdef
|
||||
title: 创建地图数据结构
|
||||
title: Create a Map Data Structure
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301629
|
||||
dashedName: create-a-map-data-structure
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
接下来的几个挑战将涵盖地图和哈希表。映射是存储键值对的数据结构。在JavaScript中,我们可以将它们作为对象使用。地图可根据键值快速查找存储的项目,是非常常见且有用的数据结构。说明:让我们开始创建自己的地图。因为JavaScript对象提供了比我们在此处编写的任何内容更有效的地图结构,所以这主要是作为学习练习。但是,JavaScript对象仅向我们提供某些操作。如果我们想定义自定义操作怎么办?使用此处提供的`Map`对象作为JavaScript `object`的包装器。在Map对象上创建以下方法和操作:
|
||||
The next few challenges will cover maps and hash tables. Maps are data structures that store key-value pairs. In JavaScript, these are available to us as objects. Maps provide rapid lookup of stored items based on key values and are very common and useful data structures.
|
||||
|
||||
- `add`接受要添加到地图的`key, value`对。
|
||||
# --instructions--
|
||||
|
||||
- `remove`接受一个键并删除关联的`key, value`对
|
||||
Let's get some practice creating our own map. Because JavaScript objects provide a much more efficient map structure than anything we could write here, this is intended primarily as a learning exercise. However, JavaScript objects only provide us with certain operations. What if we wanted to define custom operations? Use the `Map` object provided here as a wrapper around a JavaScript `object`. Create the following methods and operations on the Map object:
|
||||
|
||||
- `get`接受一个`key`并返回存储的`value`
|
||||
|
||||
- 如果密钥存在`has`接受`key`并返回
|
||||
|
||||
<dfn>true,</dfn>
|
||||
|
||||
否则返回
|
||||
|
||||
<dfn>false</dfn>
|
||||
|
||||
。
|
||||
|
||||
- `values`返回地图中所有`values`的数组
|
||||
|
||||
- `size`返回地图中的项目数
|
||||
|
||||
- `clear`清空地图
|
||||
<ul>
|
||||
<li><code>add</code> accepts a <code>key, value</code> pair to add to the map.</li>
|
||||
<li><code>remove</code> accepts a key and removes the associated <code>key, value</code> pair</li>
|
||||
<li><code>get</code> accepts a <code>key</code> and returns the stored <code>value</code></li>
|
||||
<li><code>has</code> accepts a <code>key</code> and returns <dfn>true</dfn> if the key exists or <dfn>false</dfn> if it doesn't.</li>
|
||||
<li><code>values</code> returns an array of all the values in the map</li>
|
||||
<li><code>size</code> returns the number of items in the map</li>
|
||||
<li><code>clear</code> empties the map</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
存在地图数据结构。
|
||||
The Map data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -48,7 +40,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
Map对象具有以下方法:add,remove,get,has,values,clear和size。
|
||||
The Map object should have the following methods: add, remove, get, has, values, clear, and size.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -70,7 +62,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
add方法将项添加到地图中。
|
||||
The add method should add items to the map.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -87,7 +79,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
has方法对于添加的项返回true,对于缺少的项返回false。
|
||||
The has method should return true for added items and false for absent items.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -102,7 +94,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
get方法接受键作为输入并返回关联的值。
|
||||
The get method should accept keys as input and should return the associated values.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -117,7 +109,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
values方法将存储在映射中的所有值作为数组中的字符串返回。
|
||||
The values method should return all the values stored in the map as strings in an array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -139,7 +131,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
clear方法清空映射,size方法返回映射中存在的项目数。
|
||||
The clear method should empty the map and the size method should return the number of items present in the map.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -166,7 +158,7 @@ assert(
|
||||
var Map = function() {
|
||||
this.collection = {};
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,18 +1,30 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c74
|
||||
title: 创建优先级队列类
|
||||
title: Create a Priority Queue Class
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301630
|
||||
dashedName: create-a-priority-queue-class
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在此挑战中,您将创建一个优先级队列。优先级队列是一种特殊类型的队列,其中项目可能具有指定其优先级的附加信息。这可以简单地用整数表示。项目优先级将覆盖确定序列项目已出列的放置顺序。如果具有较高优先级的项目在具有较低优先级的项目之后排队,则较高优先级项目将在所有其他项目之前出列。例如,让我们假设我们有一个包含三个项目的优先级队列: `[['kitten', 2], ['dog', 2], ['rabbit', 2]]`这里第二个值(整数)表示项目优先级。如果我们将优先级为`1` `['human', 1]`排入队列(假设优先级较低,则优先级较低),那么它将成为第一个出列的项目。该集合将是这样的: `[['human', 1], ['kitten', 2], ['dog', 2], ['rabbit', 2]]` 。我们已经开始在代码编辑器中编写`PriorityQueue` 。您需要添加一个`enqueue`方法来添加具有优先级的项目,一个用于删除项目的`dequeue`方法,一个用于返回队列中项目数量的`size`方法,一个用于返回队列`front`元素的`front`方法,以及最后一个`isEmpty`方法,如果队列为空则返回`true` ,否则返回`false` 。入`enqueue`应接受上面显示格式的项目( `['human', 1]` ),其中`1`表示优先级。 `dequeue`应该只返回当前项目,而不是其优先级。
|
||||
In this challenge you will be creating a Priority Queue. A Priority Queue is a special type of Queue in which items may have additional information which specifies their priority. This could be simply represented with an integer. Item priority will override placement order in determining the sequence items are dequeued. If an item with a higher priority is enqueued after items with lower priority, the higher priority item will be dequeued before all the others.
|
||||
|
||||
For instance, let’s imagine we have a priority queue with three items:
|
||||
|
||||
`[['kitten', 2], ['dog', 2], ['rabbit', 2]]`
|
||||
|
||||
Here the second value (an integer) represents item priority. If we enqueue `['human', 1]` with a priority of `1` (assuming lower priorities are given precedence) it would then be the first item to be dequeued. The collection would look like this:
|
||||
|
||||
`[['human', 1], ['kitten', 2], ['dog', 2], ['rabbit', 2]]`.
|
||||
|
||||
We’ve started writing a `PriorityQueue` in the code editor. You will need to add an `enqueue` method for adding items with a priority, a `dequeue` method for removing and returning items, a `size` method to return the number of items in the queue, a `front` method to return the element at the front of the queue, and finally an `isEmpty` method that will return `true` if the queue is empty or `false` if it is not.
|
||||
|
||||
The `enqueue` should accept items with the format shown above (`['human', 1]`) where `1` represents the priority. `dequeue` and `front` should return only the item's name, not its priority.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Queue`类应该有一个`enqueue`方法。
|
||||
Your `PriorityQueue` class should have a `enqueue` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +35,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`dequeue`方法。
|
||||
Your `PriorityQueue` class should have a `dequeue` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -34,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`size`方法。
|
||||
Your `PriorityQueue` class should have a `size` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -45,7 +57,18 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`isEmpty`方法。
|
||||
Your `PriorityQueue` class should have a `front` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new PriorityQueue();
|
||||
return typeof test.front === 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `PriorityQueue` class should have an `isEmpty` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -56,7 +79,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
当项目入队和出列时,您的PriorityQueue应使用`size`方法正确跟踪当前项目数。
|
||||
Your `PriorityQueue` class should correctly keep track of the current number of items using the `size` method as items are enqueued and dequeued.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -75,7 +98,34 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
当队列为空时, `isEmpty`方法应该返回`true` 。
|
||||
The `front` method should return the correct item at the front of the queue as items are enqueued and dequeued.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new PriorityQueue();
|
||||
test.enqueue(['David Brown', 2]);
|
||||
var front1 = test.front();
|
||||
test.enqueue(['Jon Snow', 1]);
|
||||
var front2 = test.front();
|
||||
test.dequeue();
|
||||
test.enqueue(['A', 3]);
|
||||
var front3 = test.front();
|
||||
test.enqueue(['B', 3]);
|
||||
test.enqueue(['C', 3]);
|
||||
test.dequeue();
|
||||
var front4 = test.front();
|
||||
return (
|
||||
front1 === 'David Brown' &&
|
||||
front2 === 'Jon Snow' &&
|
||||
front3 === 'David Brown' &&
|
||||
front4 === 'A'
|
||||
);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
The `isEmpty` method should return `true` when the queue is empty.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -91,7 +141,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
优先级队列应该在具有较低优先级的项之前返回具有较高优先级的项,否则以先进先出顺序返回项。
|
||||
The priority queue should return items with a higher priority before items with a lower priority and return items in first-in-first-out order otherwise.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,26 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c60
|
||||
title: 创建队列类
|
||||
title: Create a Queue Class
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301631
|
||||
dashedName: create-a-queue-class
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
与堆栈一样,队列是元素的集合。但与堆栈不同,队列遵循FIFO(先入先出)原则。添加到队列的元素将被推送到队列的尾部或末尾,并且只允许删除队列前面的元素。我们可以使用数组来表示队列,但就像堆栈一样,我们希望限制我们对队列的控制量。队列类的两个主要方法是enqueue和dequeue方法。 enqueue方法将元素推送到队列的尾部,dequeue方法移除并返回队列前面的元素。其他有用的方法是front,size和isEmpty方法。说明编写一个将元素推送到队列尾部的入队方法,一个删除并返回前面元素的出列方法,一个让我们看到前面元素的前方法,一个显示长度的大小方法,以及一个isEmpty方法检查队列是否为空。
|
||||
Like stacks, queues are a collection of elements. But unlike stacks, queues follow the FIFO (First-In First-Out) principle. Elements added to a queue are pushed to the tail, or the end, of the queue, and only the element at the front of the queue is allowed to be removed.
|
||||
|
||||
We could use an array to represent a queue, but just like stacks, we want to limit the amount of control we have over our queues.
|
||||
|
||||
The two main methods of a queue class is the enqueue and the dequeue method. The enqueue method pushes an element to the tail of the queue, and the dequeue method removes and returns the element at the front of the queue. Other useful methods are the front, size, and isEmpty methods.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write an `enqueue` method that pushes an element to the tail of the queue, a `dequeue` method that removes and returns the front element, a `front` method that lets us see the front element, a `size` method that shows the length, and an `isEmpty` method to check if the queue is empty.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Queue`类应该有一个`enqueue`方法。
|
||||
Your `Queue` class should have a `enqueue` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +31,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`dequeue`方法。
|
||||
Your `Queue` class should have a `dequeue` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -34,7 +42,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`front`方法。
|
||||
Your `Queue` class should have a `front` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -45,7 +53,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`size`方法。
|
||||
Your `Queue` class should have a `size` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -56,7 +64,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Queue`类应该有一个`isEmpty`方法。
|
||||
Your `Queue` class should have an `isEmpty` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -67,7 +75,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`dequeue`方法应该删除并返回队列的前端元素
|
||||
The `dequeue` method should remove and return the front element of the queue
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -80,7 +88,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`front`方法应该返回队列的front元素的值
|
||||
The `front` method should return value of the front element of the queue
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -93,7 +101,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`size`方法应该返回队列的长度
|
||||
The `size` method should return the length of the queue
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -105,7 +113,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果队列中有元素,则`isEmpty`方法应返回`false`
|
||||
The `isEmpty` method should return `false` if there are elements in the queue
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,43 +1,47 @@
|
||||
---
|
||||
id: 8d1323c8c441eddfaeb5bdef
|
||||
title: 创建一个Set类
|
||||
title: Create a Set Class
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301632
|
||||
dashedName: create-a-set-class
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在接下来的几个练习中,我们将创建一个函数来模拟一个名为“Set”的数据结构。 Set类似于数组,但不能包含重复值。 Set的典型用途是简单地检查项目是否存在。这可以用对象实现,例如:
|
||||
In this exercise we are going to create a class named `Set` to emulate an abstract data structure called "set". A set is like an array, but it cannot contain duplicate values. The typical use for a set is to simply check for the presence of an item. We can see how the ES6 `Set` object works in the example below:
|
||||
|
||||
> var set = new Object();
|
||||
> set.foo = true;
|
||||
> //看看我们的集合中是否存在foo:
|
||||
> console.log(set.foo)// true
|
||||
```js
|
||||
const set1 = new Set([1, 2, 3, 5, 5, 2, 0]);
|
||||
console.log(set1);
|
||||
// output: {1, 2, 3, 5, 0}
|
||||
console.log(set1.has(1));
|
||||
// output: true
|
||||
console.log(set1.has(6));
|
||||
// output: false
|
||||
```
|
||||
|
||||
在接下来的几个练习中,我们将从头开始构建一个全功能的Set。对于本练习,只要该值中尚不存在该值,就创建一个将值添加到set集合的函数。例如:
|
||||
First, we will create an add method that adds a value to our set collection as long as the value does not already exist in the set. Then we will create a remove method that removes a value from the set collection if it already exists. And finally, we will create a size method that returns the number of elements inside the set collection.
|
||||
|
||||
> this.add = function(element){
|
||||
> //一些代码来为集合添加值
|
||||
> }
|
||||
# --instructions--
|
||||
|
||||
如果成功添加该值,则该函数应返回`true`否则返回`false` 。
|
||||
Create an `add` method that adds a unique value to the set collection and returns `true` if the value was successfully added and `false` otherwise.
|
||||
|
||||
Create a `remove` method that accepts a value and checks if it exists in the set. If it does, then this method should remove it from the set collection, and return `true`. Otherwise, it should return `false`. Create a `size` method that returns the size of the set collection.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Set`类应该有一个`add`方法。
|
||||
Your `Set` class should have an `add` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
return typeof test.add === 'function';
|
||||
})(),
|
||||
'Your <code>Set</code> class should have an <code>add</code> method.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
您的`add`方法不应添加重复值。
|
||||
Your `add` method should not add duplicate values.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -48,12 +52,11 @@ assert(
|
||||
test.add('a');
|
||||
var vals = test.values();
|
||||
return vals[0] === 'a' && vals[1] === 'b' && vals.length === 2;
|
||||
})(),
|
||||
'Your <code>add</code> method should not add duplicate values.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
成功添加值后, `add`方法应返回`true` 。
|
||||
Your `add` method should return `true` when a value has been successfully added.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -61,12 +64,11 @@ assert(
|
||||
var test = new Set();
|
||||
var result = test.add('a');
|
||||
return result != undefined && result === true;
|
||||
})(),
|
||||
'Your <code>add</code> method should return <code>true</code> when a value has been successfully added.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`add`重复值时, `add`方法应返回`false` 。
|
||||
Your `add` method should return `false` when a duplicate value is added.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -75,8 +77,73 @@ assert(
|
||||
test.add('a');
|
||||
var result = test.add('a');
|
||||
return result != undefined && result === false;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `Set` class should have a `remove` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
return typeof test.remove === 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `remove` method should only remove items that are present in the set.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
test.add('a');
|
||||
test.add('b');
|
||||
test.remove('c');
|
||||
return test.values();
|
||||
})(),
|
||||
'Your <code>add</code> method should return <code>false</code> when a duplicate value is added.'
|
||||
['a', 'b']
|
||||
);
|
||||
```
|
||||
|
||||
Your `remove` method should remove the given item from the set.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
test.add('a');
|
||||
test.add('b');
|
||||
test.remove('a');
|
||||
var vals = test.values();
|
||||
return vals[0] === 'b' && vals.length === 1;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `Set` class should have a `size` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
return typeof test.size === 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
The `size` method should return the number of elements in the collection.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
test.add('a');
|
||||
test.add('b');
|
||||
test.remove('a');
|
||||
return test.size() === 1;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
@ -103,7 +170,7 @@ class Set {
|
||||
}
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c5f
|
||||
title: 创建一个堆栈类
|
||||
title: Create a Stack Class
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301633
|
||||
dashedName: create-a-stack-class
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在上一节中,我们讨论了堆栈是什么以及如何使用数组来表示堆栈。在本节中,我们将创建自己的堆栈类。虽然您可以使用数组来创建堆栈,但有时最好限制我们对堆栈的控制量。除了`push`和`pop`方法之外,堆栈还有其他有用的方法。让我们为我们的堆栈类添加一个`peek` , `isEmpty`和`clear`方法。说明编写一个`push`方法,将元素推送到堆栈顶部,一个`pop`方法删除堆栈顶部的元素,一个`peek`堆栈中第一个元素的`peek`方法,一个`isEmpty`方法,用于检查是否存在stack是空的,是一个`clear`堆栈中所有元素的方法。通常堆栈没有这个,但我们添加了一个控制台记录集合的`print`助手方法。
|
||||
In the last section, we talked about what a stack is and how we can use an array to represent a stack. In this section, we will be creating our own stack class. Although you can use arrays to create stacks, sometimes it is best to limit the amount of control we have with our stacks. Apart from the `push` and `pop` method, stacks have other useful methods. Let's add a `peek`, `isEmpty`, and `clear` method to our stack class.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a `push` method that pushes an element to the top of the stack, a `pop` method that removes and returns the element on the top of the stack, a `peek` method that looks at the top element in the stack, an `isEmpty` method that checks if the stack is empty, and a `clear` method that removes all elements from the stack. Normally stacks don't have this, but we've added a `print` helper method that console logs the collection.
|
||||
|
||||
# --hints--
|
||||
|
||||
你的`Stack`类应该有一个`push`方法。
|
||||
Your `Stack` class should have a `push` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +27,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
你的`Stack`类应该有一个`pop`方法。
|
||||
Your `Stack` class should have a `pop` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -34,7 +38,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
你的`Stack`类应该有一个`peek`方法。
|
||||
Your `Stack` class should have a `peek` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -45,7 +49,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`Stack`类应该有一个`isEmpty`方法。
|
||||
Your `Stack` class should have a `isEmpty` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -56,7 +60,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
你的`Stack`类应该有一个`clear`方法。
|
||||
Your `Stack` class should have a `clear` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -67,7 +71,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`peek`方法应该返回堆栈的顶部元素
|
||||
The `peek` method should return the top element of the stack
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -79,7 +83,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`pop`方法应该删除并返回堆栈的顶部元素
|
||||
The `pop` method should remove and return the top element of the stack
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -91,7 +95,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果堆栈不包含任何元素,则`isEmpty`方法应返回true
|
||||
The `isEmpty` method should return true if a stack does not contain any elements
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -102,7 +106,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`clear`方法应该从堆栈中删除所有元素
|
||||
The `clear` method should remove all element from the stack
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c84
|
||||
title: 创建Trie搜索树
|
||||
title: Create a Trie Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301634
|
||||
dashedName: create-a-trie-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在这里,我们将继续从二叉搜索树开始,看看另一种称为trie的树结构。 trie是一种常用于保存字符串的有序搜索树,或者更通用的关联数组或其中键是字符串的动态数据集。当许多键具有重叠前缀时,它们非常擅长存储数据集,例如,字典中的所有单词。与二叉树不同,节点不与实际值相关联。相反,节点的路径表示特定的键。例如,如果我们想将字符串代码存储在trie中,我们将有四个节点,每个字母对应一个节点:c - o - d - e。然后,通过所有这些节点的路径将创建代码作为字符串 - 该路径是我们存储的密钥。然后,如果我们想要添加字符串编码,它将在d之后分支之前共享前三个代码节点。通过这种方式,可以非常紧凑地存储大型数据集。此外,搜索可以非常快,因为它实际上限于您存储的字符串的长度。此外,与二叉树不同,节点可以存储任意数量的子节点。正如您可能从上面的示例中猜到的那样,一些元数据通常存储在保存密钥结尾的节点上,以便在以后的遍历中仍可以检索密钥。例如,如果我们在上面的示例中添加了代码,我们需要某种方式来知道代码中的e代表先前输入的密钥的结尾。否则,当我们添加代码时,这些信息将会丢失。说明:让我们创建一个存储单词的trie。它将通过add方法接受单词并将它们存储在trie数据结构中。它还允许我们查询给定字符串是否是带有isWord方法的单词,并使用print方法检索输入到trie中的所有单词。 isWord应该返回一个布尔值,print应该将所有这些单词的数组作为字符串值返回。为了让我们验证这个数据结构是否正确实现,我们为树中的每个节点提供了一个Node结构。每个节点都是一个具有keys属性的对象,该属性是JavaScript Map对象。这将保存作为每个节点的有效密钥的各个字母。我们还在节点上创建了一个end属性,如果节点表示单词的终止,则可以将其设置为true。
|
||||
Here we will move on from binary search trees and take a look at another type of tree structure called a trie. A trie is an ordered search tree commonly used to hold strings, or more generically associative arrays or dynamic datasets in which the keys are strings. They are very good at storing sets of data when many keys will have overlapping prefixes, for example, all the words in a dictionary. Unlike a binary tree, nodes are not associated with actual values. Instead, the path to a node represents a specific key. For instance, if we wanted to store the string code in a trie, we would have four nodes, one for each letter: c — o — d — e. Following that path through all these nodes will then create code as a string — that path is the key we stored. Then, if we wanted to add the string coding, it would share the first three nodes of code before branching away after the d. In this way, large datasets can be stored very compactly. In addition, search can be very quick because it is effectively limited to the length of the string you are storing. Furthermore, unlike binary trees a node can store any number of child nodes. As you might have guessed from the above example, some metadata is commonly stored at nodes that hold the end of a key so that on later traversals that key can still be retrieved. For instance, if we added codes in our example above we would need some way to know that the e in code represents the end of a key that was previously entered. Otherwise, this information would effectively be lost when we add codes.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Let's create a trie to store words. It will accept words through an `add` method and store these in a trie data structure. It will also allow us to query if a given string is a word with an `isWord` method, and retrieve all the words entered into the trie with a `print` method. `isWord` should return a boolean value and print should return an array of all these words as string values. In order for us to verify that this data structure is implemented correctly, we've provided a `Node` structure for each node in the tree. Each node will be an object with a `keys` property which is a JavaScript Map object. This will hold the individual letters that are valid keys of each node. We've also created an `end` property on the nodes that can be set to `true` if the node represents the termination of a word.
|
||||
|
||||
# --hints--
|
||||
|
||||
Trie有一个add方法。
|
||||
The Trie should have an add method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -28,7 +32,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
Trie有一种打印方法。
|
||||
The Trie should have a print method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -44,7 +48,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
Trie有一个isWord方法。
|
||||
The Trie should have an isWord method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -60,7 +64,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
print方法将添加到trie的所有项目作为数组中的字符串返回。
|
||||
The print method should return all items added to the trie as strings in an array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -89,7 +93,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
isWord方法仅对添加到trie的单词返回true,对所有其他单词返回false。
|
||||
The isWord method should return true only for words added to the trie and false for all other words.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -135,7 +139,7 @@ var Node = function() {
|
||||
};
|
||||
var Trie = function() {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,24 +1,28 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8d
|
||||
title: 创建ES6 JavaScript地图
|
||||
title: Create an ES6 JavaScript Map
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301635
|
||||
dashedName: create-an-es6-javascript-map
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
新版本的JavaScript为我们提供了一个内置的Map对象,它提供了我们在上一次挑战中手工编写的大部分功能。此Map对象虽然与常规JavaScript对象类似,但它提供了一些普通对象缺少的有用功能。例如,ES6 Map跟踪添加到其中的项目的插入顺序。以下是其方法的更完整概述: `.has(key)`基于键的存在返回true或false `.get(key)`返回与键相关联的值`.set(key, value)`设置新键,值对`.delete(key)`删除一个键,值对`.clear()`删除所有键值对`.entries()`以插入顺序返回所有键的数组`.values()`返回插入中所有值的数组order说明:定义一个JavaScript Map对象并为其分配一个名为myMap的变量。添加密钥,值对`freeCodeCamp` , `Awesome!`它。
|
||||
The new version of JavaScript provides us with a built-in Map object which provides much of the functionality we wrote by hand in the last challenge. This Map object, although similar to regular JavaScript objects, provides some useful functionality that normal objects lack. For example, an ES6 Map tracks the insertion order of items that are added to it. Here is a more complete overview of its methods: `.has(key)` returns true or false based on the presence of a key `.get(key)` returns the value associated with a key `.set(key, value)` sets a new key, value pair `.delete(key)` removes a key, value pair `.clear()` removes all key, value pairs `.entries()` returns an array of all the keys in insertion order `.values()` returns an array of all the values in insertion order
|
||||
|
||||
# --instructions--
|
||||
|
||||
Define a JavaScript Map object and assign to it a variable called myMap. Add the key, value pair `freeCodeCamp`, `Awesome!` to it.
|
||||
|
||||
# --hints--
|
||||
|
||||
myMap对象存在。
|
||||
The myMap object should exist.
|
||||
|
||||
```js
|
||||
assert(typeof myMap === 'object');
|
||||
```
|
||||
|
||||
myMap包含键值对`freeCodeCamp` , `Awesome!` 。
|
||||
myMap should contain the key value pair `freeCodeCamp`, `Awesome!`.
|
||||
|
||||
```js
|
||||
assert(myMap.get('freeCodeCamp') === 'Awesome!');
|
||||
@ -27,7 +31,6 @@ assert(myMap.get('freeCodeCamp') === 'Awesome!');
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
```
|
||||
|
||||
|
@ -1,30 +1,48 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c70
|
||||
title: 在ES6中创建和添加集
|
||||
title: Create and Add to Sets in ES6
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301636
|
||||
dashedName: create-and-add-to-sets-in-es6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
既然您已经完成了ES5,那么您将在ES6中执行类似的操作。这将相当容易。 ES6包含一个内置的数据结构`Set`现在包含了您手动编写的许多操作。我们来看看:创建一个新的空集: `var set = new Set();`您可以使用值创建一个集合: `var set = new Set(1);`您可以使用数组创建一个集合: `var set = new Set([1, 2, 3]);`创建集合后,可以使用`add`方法添加所需的值:
|
||||
Now that you have worked through ES5, you are going to perform something similar in ES6. This will be considerably easier. ES6 contains a built-in data structure `Set` so many of the operations you wrote by hand are now included for you. Let's take a look:
|
||||
|
||||
> var set = new Set(\[1,2,3]);
|
||||
> set.add(\[4,5,6]);
|
||||
To create a new empty set:
|
||||
|
||||
提醒一下,集合是一种不能包含重复值的数据结构:
|
||||
`var set = new Set();`
|
||||
|
||||
> var set = new Set(\[1,2,3,1,2,3]);
|
||||
> // set仅包含\[1,2,3]
|
||||
You can create a set with a value:
|
||||
|
||||
`var set = new Set(1);`
|
||||
|
||||
You can create a set with an array:
|
||||
|
||||
`var set = new Set([1, 2, 3]);`
|
||||
|
||||
Once you have created a set, you can add the values you wish using the `add` method:
|
||||
|
||||
```js
|
||||
var set = new Set([1, 2, 3]);
|
||||
set.add([4, 5, 6]);
|
||||
```
|
||||
|
||||
As a reminder, a set is a data structure that cannot contain duplicate values:
|
||||
|
||||
```js
|
||||
var set = new Set([1, 2, 3, 1, 2, 3]);
|
||||
// set contains [1, 2, 3] only
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
在本练习中,返回一个具有以下值的集合: `1, 2, 3, 'Taco', 'Cat', 'Awesome'`
|
||||
For this exercise, return a set with the following values: `1, 2, 3, 'Taco', 'Cat', 'Awesome'`
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Set`应该只包含值`1, 2, 3, Taco, Cat, Awesome` 。
|
||||
Your `Set` should only contain the values `1, 2, 3, Taco, Cat, Awesome`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c80
|
||||
title: 删除二进制搜索树中的叶节点
|
||||
title: Delete a Leaf Node in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301637
|
||||
dashedName: delete-a-leaf-node-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
这是我们将在二叉搜索树中实现更难操作的三个挑战中的第一个:删除。删除很困难,因为删除节点会破坏树中的链接。必须仔细重新建立这些链接以确保维护二叉树结构。对于某些删除,这意味着必须重新排列树。通常,在尝试删除节点时,您将遇到以下三种情况之一:叶节点:要删除的目标没有子节点。一个孩子:要删除的目标只有一个孩子。两个子节点:要删除的目标有两个子节点。删除叶节点很简单,我们只需删除它。删除具有一个子节点的节点也相对容易,我们只需删除它并将其父节点链接到我们删除的节点的子节点。但是,删除具有两个子节点的节点更加困难,因为这会创建两个需要重新连接到父树的子节点。我们将在第三个挑战中看到如何处理这个案例。此外,在处理删除时,您需要注意一些边缘情况。如果树是空的怎么办?如果要删除的节点是根节点怎么办?如果树中只有两个元素怎么办?现在,让我们处理第一种删除叶节点的情况。说明:在我们的二叉树上创建一个名为`remove` 。我们将在这里为我们的删除操作构建逻辑。首先,您需要在remove中创建一个函数,该函数在当前树中找到我们尝试删除的节点。如果树中不存在该节点,则`remove`应返回`null` 。现在,如果目标节点是没有子节点的叶节点,则应将其父节点引用设置为`null` 。这有效地从树中删除节点。为此,您必须跟踪我们尝试删除的节点的父节点。创建一种跟踪目标节点具有的子节点数的方法也很有用,因为这将确定我们的删除属于哪种情况。我们将在下一次挑战中处理第二和第三个案例。祝你好运!
|
||||
This is the first of three challenges where we will implement a more difficult operation in binary search trees: deletion. Deletion is difficult because removing nodes breaks links in the tree. These links must be carefully reestablished to ensure the binary tree structure is maintained. For some deletions, this means the tree must be rearranged. In general, you will encounter one of three cases when trying to delete a node: Leaf Node: The target to delete has zero children. One Child: The target to delete only has one child. Two Children: The target to delete has two child nodes. Removing a leaf node is easy, we simply remove it. Deleting a node with one child is also relatively easy, we simply remove it and link its parent to child of the node we deleted. Removing a node with two children is more difficult, however, because this creates two child nodes that need to be reconnected to the parent tree. We'll see how to deal with this case in the third challenge. Additionally, you need to be mindful of some edge cases when handling deletion. What if the tree is empty? What if the node to delete is the root node? What if there are only two elements in the tree? For now, let's handle the first case where we delete a leaf node.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Create a method on our binary tree called `remove`. We'll build the logic for our deletion operation in here. First, you'll want to create a function within remove that finds the node we are trying to delete in the current tree. If the node is not present in the tree, `remove` should return `null`. Now, if the target node is a leaf node with no children, then the parent reference to it should be set to `null`. This effectively deletes the node from the tree. To do this, you will have to keep track of the parent of the node we are trying to delete as well. It will also be useful to create a way to track the number of children the target node has, as this will determine which case our deletion falls under. We will handle the second and third cases in the next challenges. Good luck!
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`remove`的方法。
|
||||
The binary search tree should have a method called `remove`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
尝试删除不存在的元素将返回`null` 。
|
||||
Trying to remove an element that does not exist should return `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -61,7 +65,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果根节点没有子节点,则删除它会将根节点设置为`null` 。
|
||||
If the root node has no children, deleting it should set the root to `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -82,7 +86,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法从树中删除叶节点
|
||||
The `remove` method should remove leaf nodes from the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c81
|
||||
title: 在二叉搜索树中删除具有一个子节点的节点
|
||||
title: Delete a Node with One Child in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301638
|
||||
dashedName: delete-a-node-with-one-child-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们可以删除叶子节点,让我们继续第二种情况:删除一个子节点。对于这种情况,假设我们有一棵树,其中包含以下节点1 - 2 - 3,其中1是根。要删除2,我们只需要在1到3中做出正确的引用。更一般地说,为了删除只有一个子节点的节点,我们将该节点的父引用作为树中的下一个节点。说明:我们在`remove`方法中提供了一些代码,用于完成上一次挑战中的任务。我们找到要删除的目标及其父节点,并定义目标节点具有的子节点数。让我们在这里为仅有一个子节点的目标节点添加下一个案例。在这里,我们必须确定单个子节点是树中的左或右分支,然后在父节点中设置正确的引用以指向此节点。另外,让我们考虑目标是根节点的情况(这意味着父节点将为`null` )。只要通过测试,请随意用自己的代码替换所有入门代码。
|
||||
Now that we can delete leaf nodes let's move on to the second case: deleting a node with one child. For this case, say we have a tree with the following nodes 1 — 2 — 3 where 1 is the root. To delete 2, we simply need to make the right reference in 1 point to 3. More generally to delete a node with only one child, we make that node's parent reference the next node in the tree.
|
||||
|
||||
# --instructions--
|
||||
|
||||
We've provided some code in our `remove` method that accomplishes the tasks from the last challenge. We find the target to delete and its parent and define the number of children the target node has. Let's add the next case here for target nodes with only one child. Here, we'll have to determine if the single child is a left or right branch in the tree and then set the correct reference in the parent to point to this node. In addition, let's account for the case where the target is the root node (this means the parent node will be `null`). Feel free to replace all the starter code with your own as long as it passes the tests.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`remove`的方法。
|
||||
The binary search tree should have a method called `remove`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
尝试删除不存在的元素将返回`null` 。
|
||||
Trying to remove an element that does not exist should return `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -61,7 +65,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果根节点没有子节点,则删除它会将根节点设置为`null` 。
|
||||
If the root node has no children, deleting it should set the root to `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -82,7 +86,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法从树中删除叶节点
|
||||
The `remove` method should remove leaf nodes from the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -110,7 +114,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法删除具有一个子节点的节点。
|
||||
The `remove` method should remove nodes with one child.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -136,7 +140,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
删除具有两个节点的树中的根将第二个节点设置为根。
|
||||
Removing the root in a tree with two nodes should set the second to be the root.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c82
|
||||
title: 在二叉搜索树中删除具有两个子节点的节点
|
||||
title: Delete a Node with Two Children in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301639
|
||||
dashedName: delete-a-node-with-two-children-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
删除具有两个子节点的节点是最难实现的。删除这样的节点会生成两个不再连接到原始树结构的子树。我们如何重新连接它们?一种方法是在目标节点的右子树中找到最小值,并用该值替换目标节点。以这种方式选择替换确保它大于左子树中的每个节点,它成为新的父节点,但也小于右子树中的每个节点,它成为新的父节点。完成此替换后,必须从右子树中删除替换节点。即使这个操作也很棘手,因为替换可能是一个叶子,或者它本身可能是一个右子树的父亲。如果是叶子,我们必须删除其父对它的引用。否则,它必须是目标的正确子项。在这种情况下,我们必须用替换值替换目标值,并使目标引用替换的右子。说明:让我们通过处理第三种情况来完成我们的`remove`方法。我们为前两种情况再次提供了一些代码。现在添加一些代码来处理具有两个子节点的目标节点。任何边缘情况要注意?如果树只有三个节点怎么办?完成后,这将完成二进制搜索树的删除操作。干得好,这是一个非常难的问题!
|
||||
Removing nodes that have two children is the hardest case to implement. Removing a node like this produces two subtrees that are no longer connected to the original tree structure. How can we reconnect them? One method is to find the smallest value in the right subtree of the target node and replace the target node with this value. Selecting the replacement in this way ensures that it is greater than every node in the left subtree it becomes the new parent of but also less than every node in the right subtree it becomes the new parent of. Once this replacement is made the replacement node must be removed from the right subtree. Even this operation is tricky because the replacement may be a leaf or it may itself be the parent of a right subtree. If it is a leaf we must remove its parent's reference to it. Otherwise, it must be the right child of the target. In this case, we must replace the target value with the replacement value and make the target reference the replacement's right child.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Let's finish our `remove` method by handling the third case. We've provided some code again for the first two cases. Add some code now to handle target nodes with two children. Any edge cases to be aware of? What if the tree has only three nodes? Once you are finished this will complete our deletion operation for binary search trees. Nice job, this is a pretty hard problem!
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`remove`的方法。
|
||||
The binary search tree should have a method called `remove`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
尝试删除不存在的元素将返回`null` 。
|
||||
Trying to remove an element that does not exist should return `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +62,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果根节点没有子节点,则删除它会将根节点设置为`null` 。
|
||||
If the root node has no children, deleting it should set the root to `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -76,7 +80,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法从树中删除叶节点
|
||||
The `remove` method should remove leaf nodes from the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -103,7 +107,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法删除具有一个子节点的节点。
|
||||
The `remove` method should remove nodes with one child.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -129,7 +133,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
删除具有两个节点的树中的根将第二个节点设置为根。
|
||||
Removing the root in a tree with two nodes should set the second to be the root.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -151,7 +155,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`remove`方法在保留二叉搜索树结构的同时删除具有两个子节点的节点。
|
||||
The `remove` method should remove nodes with two children while maintaining the binary search tree structure.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -208,7 +212,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
可以在三个节点的树上删除根。
|
||||
The root should be removable on a tree of three nodes.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,26 +1,38 @@
|
||||
---
|
||||
id: 587d825d367417b2b2512c96
|
||||
title: 深度优先搜索
|
||||
title: Depth-First Search
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301640
|
||||
dashedName: depth-first-search
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
与<dfn>广度优先搜索</dfn>类似,这里我们将学习另一种称为<dfn>深度优先搜索的</dfn>图遍历算法。广度优先搜索搜索远离源节点的增量边长度,而<dfn>深度优先搜索</dfn>首先尽可能地沿着边缘路径向下<dfn>搜索</dfn> 。一旦到达路径的一端,搜索将回溯到具有未访问边缘路径的最后一个节点并继续搜索。在视觉上,这就是算法正在做的事情,其中顶部节点是搜索的起始点。
|
||||
Similar to <dfn>breadth-first search</dfn>, here we will learn about another graph traversal algorithm called <dfn>depth-first search</dfn>.
|
||||
|
||||
<img class='img-responsive' src='https://camo.githubusercontent.com/aaad9e39961daf34d967c616edeb50abf3bf1235/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f372f37662f44657074682d46697273742d5365617263682e676966'>
|
||||
Whereas the breadth-first search searches incremental edge lengths away from the source node, <dfn>depth-first search</dfn> first goes down a path of edges as far as it can.
|
||||
|
||||
该算法的简单输出是可从给定节点到达的节点列表。因此,在实施此算法时,您需要跟踪您访问的节点。
|
||||
Once it reaches one end of a path, the search will backtrack to the last node with an un-visited edge path and continue searching.
|
||||
|
||||
The animation below shows how the algorithm works. The algorithm starts with the top node and visits the nodes in the numbered order.
|
||||
|
||||
<img class='img-responsive' src='https://camo.githubusercontent.com/aaad9e39961daf34d967c616edeb50abf3bf1235/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f372f37662f44657074682d46697273742d5365617263682e676966' />
|
||||
|
||||
Notice how, unlike breadth-first search, every time a node is visited, it doesn't visit all of its neighbors. Instead, it first visits one of its neighbors and continues down that path until there are no more nodes to be visited on that path.
|
||||
|
||||
To implement this algorithm, you'll want to use a stack. A stack is an array where the last element added is the first to be removed. This is also known as a <dfn>Last-In-First-Out</dfn> data structure. A stack is helpful in depth-first search algorithms because, as we add neighbors to the stack, we want to visit the most recently added neighbors first and remove them from the stack.
|
||||
|
||||
A simple output of this algorithm is a list of nodes which are reachable from a given node. Therefore, you'll also want to keep track of the nodes you visit.
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写一个函数`dfs()` ,它将无向,邻接矩阵`graph`和节点标签`root`作为参数。节点标签将只是`0`和`n - 1`之间节点的数值,其中`n`是图中节点的总数。您的函数应输出从`root`可到达的所有节点的数组。
|
||||
Write a function `dfs()` that takes an undirected, adjacency matrix `graph` and a node label `root` as parameters. The node label will just be the numeric value of the node between `0` and `n - 1`, where `n` is the total number of nodes in the graph.
|
||||
|
||||
Your function should output an array of all nodes reachable from `root`.
|
||||
|
||||
# --hints--
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` ,起始节点为`1`应返回一个数组`0` , `1` , `2` ,和`3` 。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` with a start node of `1` should return an array with `0`, `1`, `2`, and `3`.
|
||||
|
||||
```js
|
||||
assert.sameMembers(
|
||||
@ -37,7 +49,7 @@ assert.sameMembers(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` ,起始节点为`1`应该返回一个包含四个元素的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]` with a start node of `1` should return an array with four elements.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -53,7 +65,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` ,起始节点为`3`应该返回一个`3`的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` with a start node of `3` should return an array with `3`.
|
||||
|
||||
```js
|
||||
assert.sameMembers(
|
||||
@ -70,7 +82,7 @@ assert.sameMembers(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` ,起始节点为`3`应该返回一个包含一个元素的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]` with a start node of `3` should return an array with one element.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -86,7 +98,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` ,起始节点为`3`应该返回一个`2`和`3`的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` with a start node of `3` should return an array with `2` and `3`.
|
||||
|
||||
```js
|
||||
assert.sameMembers(
|
||||
@ -103,7 +115,7 @@ assert.sameMembers(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` ,起始节点为`3`应该返回一个包含两个元素的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` with a start node of `3` should return an array with two elements.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -119,7 +131,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` ,起始节点为`0`应该返回一个`0`和`1`的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` with a start node of `0` should return an array with `0` and `1`.
|
||||
|
||||
```js
|
||||
assert.sameMembers(
|
||||
@ -136,7 +148,7 @@ assert.sameMembers(
|
||||
);
|
||||
```
|
||||
|
||||
输入图`[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` ,起始节点为`0`应该返回一个包含两个元素的数组。
|
||||
The input graph `[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]` with a start node of `0` should return an array with two elements.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,26 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7d
|
||||
title: 找到二叉搜索树的最小和最大高度
|
||||
title: Find the Minimum and Maximum Height of a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301641
|
||||
dashedName: find-the-minimum-and-maximum-height-of-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在最后一个挑战中,我们描述了树可能变得不平衡的情景。为了理解平衡的概念,让我们看看另一个树属性:高度。树中的高度表示从根节点到任何给定叶节点的距离。高度分支的树结构中的不同路径可以具有不同的高度,但是对于给定的树,将具有最小和最大高度。如果树是平衡的,则这些值最多相差一个。这意味着在平衡树中,所有叶节点都存在于同一级别中,或者如果它们不在同一级别内,则它们最多相隔一个级别。平衡的属性对于树很重要,因为它决定了树操作的效率。正如我们在上一次挑战中所解释的那样,我们面临严重不平衡树木的最坏情况时间复杂性。自平衡树通常用于在具有动态数据集的树中解决此问题。这些的常见例子包括AVL树,红黑树和B树。这些树都包含额外的内部逻辑,当插入或删除创建不平衡状态时,它会重新平衡树。注意:与height相似的属性是depth,它指的是给定节点距根节点的距离。说明:为我们的二叉树编写两种方法: `findMinHeight`和`findMaxHeight` 。这些方法应分别返回给定二叉树内最小和最大高度的整数值。如果节点为空,请为其指定高度`-1` (这是基本情况)。最后,添加第三个方法`isBalanced` ,它返回`true`或`false`具体取决于树是否平衡。您可以使用刚才编写的前两种方法来确定这一点。
|
||||
In the last challenge we described a scenario in which a tree could become unbalanced. To understand the concept of balance, let's take a look at another tree property: height. Height in a tree represents the distance from the root node to any given leaf node. Different paths in a highly branched tree structure may have different heights, but for a given tree there will be a minimum and maximum height. If the tree is balanced, these values will differ at most by one. This means that in a balanced tree, all the leaf nodes exist within the same level, or if they are not within the same level they are at most one level apart.
|
||||
|
||||
The property of balance is important for trees because it is what determines the efficiency of tree operations. As we explained in the last challenge, we face worst case time complexity for heavily unbalanced trees. Self-balancing trees are commonly used to account for this issue in trees with dynamic data sets. Common examples of these include AVL trees, red-black trees, and B-trees. These trees all contain additional internal logic which re-balance the tree when insertions or deletions create a state of imbalance.
|
||||
|
||||
**Note:** A similar property to height is depth, which refers to how far a given node is from the root node.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write two methods for our binary tree: `findMinHeight` and `findMaxHeight`. These methods should return an integer value for the minimum and maximum height within a given binary tree, respectively. If the node is empty let's assign it a height of `-1` (that's the base case). Finally, add a third method `isBalanced` which returns `true` or `false` depending on whether the tree is balanced or not. You can use the first two methods you just wrote to determine this.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +34,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`findMinHeight`的方法。
|
||||
The binary search tree should have a method called `findMinHeight`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +50,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`findMaxHeight`的方法。
|
||||
The binary search tree should have a method called `findMaxHeight`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +66,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`isBalanced`的方法。
|
||||
The binary search tree should have a method called `isBalanced`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -74,7 +82,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`findMinHeight`方法返回树的最小高度。
|
||||
The `findMinHeight` method should return the minimum height of the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -101,7 +109,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`findMaxHeight`方法返回树的最大高度。
|
||||
The `findMaxHeight` method should return the maximum height of the tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -128,7 +136,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
空树返回高度`-1` 。
|
||||
An empty tree should return a height of `-1`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -147,7 +155,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
如果树是平衡二叉搜索树,则`isBalanced`方法返回true。
|
||||
The `isBalanced` method should return `false` if the tree is an unbalanced binary search tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -169,7 +177,33 @@ assert(
|
||||
test.add(45);
|
||||
test.add(73);
|
||||
test.add(8);
|
||||
return !test.isBalanced();
|
||||
return test.isBalanced() === false;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
The `isBalanced` method should return `true` if the tree is a balanced binary search tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = false;
|
||||
if (typeof BinarySearchTree !== 'undefined') {
|
||||
test = new BinarySearchTree();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (typeof test.isBalanced !== 'function') {
|
||||
return false;
|
||||
}
|
||||
test.add(10);
|
||||
test.add(3);
|
||||
test.add(22);
|
||||
test.add(1);
|
||||
test.add(4);
|
||||
test.add(17);
|
||||
test.add(32);
|
||||
return test.isBalanced() === true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
@ -227,7 +261,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
@ -244,7 +278,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
this.findMinHeight = function(root = this.root) {
|
||||
// empty tree.
|
||||
|
@ -1,20 +1,18 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c7a
|
||||
title: 在二叉搜索树中查找最小值和最大值
|
||||
title: Find the Minimum and Maximum Value in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301642
|
||||
dashedName: find-the-minimum-and-maximum-value-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
这一系列挑战将介绍树数据结构。树木是计算机科学中重要且通用的数据结构。当然,他们的名字来源于这样一个事实:当他们看到它们时,它们看起来很像我们在自然界中熟悉的树木。树数据结构以一个节点(通常称为根)开始,并从此处分支到其他节点,每个节点可以具有更多子节点,依此类推。数据结构通常以顶部的根节点可视化;你可以把它想象成一棵倒置的天然树。首先,让我们描述一下我们将在树上遇到的一些常用术语。根节点是树的顶部。树中的数据点称为节点。具有通向其他节点的分支的节点被称为分支通向的节点的父节点(子节点)。其他更复杂的家庭术语适用于您所期望的。子树是指特定节点的所有后代,分支可以称为边,而叶节点是树末端没有子节点的节点。最后,请注意树本质上是递归数据结构。也就是说,节点的任何子节点都是其子树的父节点,依此类推。在为常见树操作设计算法时,树的递归性质非常重要。首先,我们将讨论一种特定类型的树,即二叉树。实际上,我们实际上将讨论一个特定的二叉树,一个二叉搜索树。让我们来描述这意味着什么。虽然树数据结构可以在单个节点上具有任意数量的分支,但是二叉树对于每个节点只能具有两个分支。此外,针对子子树排序二叉搜索树,使得左子树中的每个节点的值小于或等于父节点的值,并且右子树中的每个节点的值是大于或等于父节点的值。
|
||||
|
||||
现在这个有序的关系很容易看到。请注意,根节点8左侧的每个值都小于8,右侧的每个值都大于8.还要注意,此关系也适用于每个子树。例如,第一个左子项是子树。 3是父节点,它有两个子节点 - 通过控制二进制搜索树的规则,我们知道甚至没有看到这个节点的左子节点(及其任何子节点)将小于3,右边child(及其任何子级)将大于3(但也小于结构的根值),依此类推。二进制搜索树是非常常见且有用的数据结构,因为它们在几种常见操作(例如查找,插入和删除)的平均情况下提供对数时间。说明:我们将从简单开始。除了为树创建节点的函数之外,我们还在这里定义了二叉搜索树结构的骨架。观察每个节点可能具有左右值。如果它们存在,将为它们分配子子树。在我们的二叉搜索树中,定义两个方法, `findMin`和`findMax` 。这些方法应返回二叉搜索树中保存的最小值和最大值(不用担心现在向树中添加值,我们在后台添加了一些值)。如果遇到困难,请反思二进制搜索树必须为true的不变量:每个左子树小于或等于其父树,每个右子树大于或等于其父树。我们还要说我们的树只能存储整数值。如果树为空,则任一方法都应返回`null` 。
|
||||
In this challenge you will define two methods, `findMin` and `findMax`. These methods should return the minimum and maximum value held in the binary search tree (don't worry about adding values to the tree for now, we have added some in the background). If you get stuck, reflect on the invariant that must be true for binary search trees: each left subtree is less than or equal to its parent and each right subtree is greater than or equal to its parent. Let's also say that our tree can only store integer values. If the tree is empty, either method should return `null`.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -28,7 +26,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`findMin`的方法。
|
||||
The binary search tree should have a method called `findMin`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -44,7 +42,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`findMax`的方法。
|
||||
The binary search tree should have a method called `findMax`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -60,7 +58,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`findMin`方法返回二叉搜索树中的最小值。
|
||||
The `findMin` method should return the minimum value in the binary search tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -87,7 +85,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`findMax`方法返回二叉搜索树中的最大值。
|
||||
The `findMax` method should return the maximum value in the binary search tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -114,7 +112,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`findMin`和`findMax`方法为空树返回`null` 。
|
||||
The `findMin` and `findMax` methods should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -189,7 +187,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,24 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8c
|
||||
title: 用最小堆实现堆排序
|
||||
title: Implement Heap Sort with a Min Heap
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301643
|
||||
dashedName: implement-heap-sort-with-a-min-heap
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们可以添加和删除元素,让我们看看堆可用于的一些应用程序。堆通常用于实现优先级队列,因为它们始终将最大值或最小值的项存储在第一个位置。此外,它们还用于实现称为堆排序的排序算法。我们将在这里看到如何做到这一点。堆排序使用最小堆,与最大堆相反。最小堆始终将最小值的元素存储在根位置。堆排序通过获取未排序的数组,将数组中的每个项目添加到最小堆中,然后将最小堆中的每个项目提取到新数组中。最小堆结构确保新数组将包含至少最大顺序的原始项。这是最有效的排序算法之一,具有O(nlog(n))的平均和最差情况性能。说明:让我们用最小堆实现堆排序。您可以在此处调整最大堆代码。使用insert,remove和sort方法创建一个MinHeap对象。 sort方法应返回最小堆中从最小到最大排序的所有元素的数组。
|
||||
Now that we can add and remove elements let's see some of the applications heaps can be used for. Heaps are commonly used to implement priority queues because they always store an item of greatest or least value in first position. In addition, they are used to implement a sorting algorithm called heap sort. We'll see how to do this here. Heap sort uses a min heap, the reverse of a max heap. A min heap always stores the element of least value in the root position.
|
||||
|
||||
Heap sort works by taking an unsorted array, adding each item in the array into a min heap, and then extracting every item out of the min heap into a new array. The min heap structure ensures that the new array will contain the original items in least to greatest order. This is one of the most efficient sorting algorithms with average and worst case performance of O(nlog(n)).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Let's implement heap sort with a min heap. Feel free to adapt your max heap code here. Create an object `MinHeap` with `insert`, `remove`, and `sort` methods. The `sort` method should return an array of all the elements in the min heap sorted from smallest to largest.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在MinHeap数据结构。
|
||||
The MinHeap data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +32,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MinHeap有一个名为insert的方法。
|
||||
MinHeap should have a method called insert.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +48,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MinHeap有一个名为remove的方法。
|
||||
MinHeap should have a method called remove.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +64,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MinHeap有一个名为sort的方法。
|
||||
MinHeap should have a method called sort.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -74,28 +80,31 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
sort方法返回一个数组,其中包含按排序顺序添加到最小堆的所有项。
|
||||
The sort method should return an array containing all items added to the min heap in sorted order.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = false;
|
||||
if (typeof MinHeap !== 'undefined') {
|
||||
test = new MinHeap();
|
||||
} else {
|
||||
(() => {
|
||||
if (typeof MinHeap === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
test.insert(3);
|
||||
test.insert(12);
|
||||
test.insert(5);
|
||||
test.insert(10);
|
||||
test.insert(1);
|
||||
test.insert(27);
|
||||
test.insert(42);
|
||||
test.insert(57);
|
||||
test.insert(5);
|
||||
var result = test.sort();
|
||||
return isSorted(result);
|
||||
|
||||
const heap = new MinHeap();
|
||||
const arr = createRandomArray(25);
|
||||
|
||||
for (let i of arr) {
|
||||
heap.insert(i);
|
||||
}
|
||||
|
||||
const result = heap.sort();
|
||||
arr.sort((a, b) => a - b);
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] !== result[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
@ -116,14 +125,14 @@ function createRandomArray(size = 5){
|
||||
let a = new Array(size);
|
||||
for(let i = 0; i < size; i++)
|
||||
a[i] = Math.floor(Math.random() * 100);
|
||||
|
||||
|
||||
return a;
|
||||
}
|
||||
const array = createRandomArray(25);
|
||||
|
||||
var MinHeap = function() {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,69 +1,60 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c79
|
||||
title: 发生率矩阵
|
||||
title: Incidence Matrix
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301644
|
||||
dashedName: incidence-matrix
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
表示图形的另一种方式是将其置于<dfn>关联矩阵中。</dfn> <dfn>入射矩阵</dfn>是二维(2D)阵列。一般而言,关联矩阵在其两个维度之间涉及两个不同类别的对象。这种矩阵类似于邻接矩阵。但是,行和列在这里意味着其他东西。在图表中,我们有边缘和节点。这些将是我们的“两类不同的对象”。该矩阵将使行为节点,列为边。这意味着我们可以拥有不均匀的行数和列数。每列将代表一个独特的边缘。此外,每个边连接两个节点。要显示两个节点之间存在边缘,您将在特定列的两行中放置1。下面是一个3节点图,节点1和节点3之间有一条边。
|
||||
Yet another way to represent a graph is to put it in an <dfn>incidence matrix.</dfn>
|
||||
|
||||
> 1
|
||||
>
|
||||
> * * *
|
||||
>
|
||||
> 1 | 1
|
||||
> 2 | 0
|
||||
> 3 | 1
|
||||
An <dfn>incidence matrix</dfn> is a two-dimensional (2D) array. Generally speaking, an incidence matrix relates two different classes of objects between its two dimensions. This kind of matrix is similar to an adjacency matrix. However, the rows and columns mean something else here.
|
||||
|
||||
以下是具有4个边和4个节点的`incidence matrix`的示例。请记住,列是边,行是节点本身。
|
||||
In graphs, we have edges and nodes. These will be our "two different classes of objects". This matrix will have the rows be the nodes and columns be the edges. This means that we can have an uneven number of rows and columns.
|
||||
|
||||
> 1 2 3 4
|
||||
>
|
||||
> * * *
|
||||
>
|
||||
> 1 | 0 1 1 1
|
||||
> 2 | 1 1 0 0
|
||||
> 3 | 1 0 0 1
|
||||
> 4 | 0 0 1 0
|
||||
Each column will represent a unique edge. Also, each edge connects two nodes. To show that there is an edge between two nodes, you will put a 1 in the two rows of a particular column. Below is a 3 node graph with one edge between node 1 and node 3.
|
||||
|
||||
下面是同一件事的JavaScript实现。
|
||||
<blockquote> 1<br> ---<br>1 | 1<br>2 | 0<br>3 | 1</blockquote>
|
||||
|
||||
> var incMat = \[
|
||||
> \[0,1,1,1],
|
||||
> \[1,1,0,0],
|
||||
> \[1,0,0,1],
|
||||
> \[0,0,1,0]
|
||||
> ]。
|
||||
Here is an example of an `incidence matrix` with 4 edges and 4 nodes. Remember, the columns are the edges and rows are the nodes themselves.
|
||||
|
||||
要制作有向图,请使用`-1`表示离开特定节点的边,使用`1`作为边进入节点。
|
||||
<blockquote> 1 2 3 4<br> --------<br>1 | 0 1 1 1<br>2 | 1 1 0 0<br>3 | 1 0 0 1<br>4 | 0 0 1 0</blockquote>
|
||||
|
||||
> var incMatDirected = \[
|
||||
> \[0,-1,1,-1],
|
||||
> \[-1,1,0,0],
|
||||
> \[1,0,0,1],
|
||||
> \[0,0,-1,0]
|
||||
> ]。
|
||||
Below is a JavaScript implementation of the same thing.
|
||||
|
||||
图形的边缘也可以有权
|
||||
```js
|
||||
var incMat = [
|
||||
[0, 1, 1, 1],
|
||||
[1, 1, 0, 0],
|
||||
[1, 0, 0, 1],
|
||||
[0, 0, 1, 0]
|
||||
];
|
||||
```
|
||||
|
||||
<dfn>重</dfn>
|
||||
To make a directed graph, use `-1` for an edge leaving a particular node and `1` for an edge entering a node.
|
||||
|
||||
。到目前为止,我们有
|
||||
```js
|
||||
var incMatDirected = [
|
||||
[ 0, -1, 1, -1],
|
||||
[-1, 1, 0, 0],
|
||||
[ 1, 0, 0, 1],
|
||||
[ 0, 0, -1, 0]
|
||||
];
|
||||
```
|
||||
|
||||
<dfn>未加权的</dfn>
|
||||
|
||||
边缘,只有存在和缺少边是二进制( `0`或`1` )。根据您的应用,您可以拥有不同的重量。不同的权重表示为大于1的数字。
|
||||
Graphs can also have <dfn>weights</dfn> on their edges. So far, we have <dfn>unweighted</dfn> edges where just the presence and lack of edge is binary (`0` or `1`). You can have different weights depending on your application. A different weight is represented as numbers greater than 1.
|
||||
|
||||
# --instructions--
|
||||
|
||||
创建具有五个节点和四个边的无向图的关联矩阵。该矩阵应该是多维数组。这五个节点在关系之后具有关系。第一边缘在第一和第二节点之间。第二个边缘位于第二个和第三个节点之间。第三个边缘位于第三个和第五个节点之间。并且四个边缘在第四和第二节点之间。所有边权重均为1,边缘顺序很重要。
|
||||
Create an incidence matrix of an undirected graph with five nodes and four edges. This matrix should be in a multi-dimensional array.
|
||||
|
||||
These five nodes have the following relationships. The first edge is between the first and second node. The second edge is between the second and third node. The third edge is between the third and fifth node. The fourth edge is between the fourth and second node. All edge weights are one and the edge order matters.
|
||||
|
||||
# --hints--
|
||||
|
||||
`incMatUndirected`应该只包含五个节点。
|
||||
`incMatUndirected` should only contain five nodes.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -78,25 +69,25 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
第一个和第二个节点之间应该有第一条边。
|
||||
There should be a first edge between the first and second node.
|
||||
|
||||
```js
|
||||
assert(incMatUndirected[0][0] === 1 && incMatUndirected[1][0] === 1);
|
||||
```
|
||||
|
||||
第二个和第三个节点之间应该有第二条边。
|
||||
There should be a second edge between the second and third node.
|
||||
|
||||
```js
|
||||
assert(incMatUndirected[1][1] === 1 && incMatUndirected[2][1] === 1);
|
||||
```
|
||||
|
||||
第三个和第五个节点之间应该有第三条边。
|
||||
There should be a third edge between the third and fifth node.
|
||||
|
||||
```js
|
||||
assert(incMatUndirected[2][2] === 1 && incMatUndirected[4][2] === 1);
|
||||
```
|
||||
|
||||
第二个和第四个节点之间应该有第四条边。
|
||||
There should be a fourth edge between the second and fourth node.
|
||||
|
||||
```js
|
||||
assert(incMatUndirected[1][3] === 1 && incMatUndirected[3][3] === 1);
|
||||
|
@ -1,18 +1,50 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c8a
|
||||
title: 将元素插入最大堆
|
||||
title: Insert an Element into a Max Heap
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301703
|
||||
dashedName: insert-an-element-into-a-max-heap
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们将继续讨论另一个树数据结构,即二进制堆。二进制堆是部分有序的二叉树,它满足堆属性。 heap属性指定父节点和子节点之间的关系。您可能有一个最大堆,其中所有父节点都大于或等于其子节点,或者最小堆,其中反向为真。二进制堆也是完整的二叉树。这意味着树的所有级别都被完全填充,如果最后一级被部分填充,则从左到右填充。虽然二进制堆可以实现为具有包含左和右引用的节点的树结构,但是根据堆属性的部分排序允许我们用数组表示堆。父子关系是我们感兴趣的,通过简单的算术,我们可以计算任何父节点的子节点和任何子节点的父节点。例如,考虑二进制最小堆的数组表示: `[ 6, 22, 30, 37, 63, 48, 42, 76 ]`根节点是第一个元素,6。它的子节点是22和30.如果我们看在这些值的数组索引之间的关系中,对于索引i,子项为2 \* i + 1和2 \* i + 2.同样,索引0处的元素是索引1和2处的这两个子项的父项。通常,我们可以在任何索引处找到节点的父节点,其中包含以下内容:(i - 1)/ 2.当二叉树增长到任意大小时,这些模式将成立。最后,我们可以稍微调整一下,通过跳过数组中的第一个元素,使这个算法更容易。这样做会为给定索引i处的任何元素创建以下关系:示例数组表示形式: `[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]`元素的左子项:i \* 2元素的右子项:i \* 2 + 1一个元素的父元素:i / 2一旦你绕过数学运算,使用数组表示非常有用,因为使用这个算法可以快速确定节点位置,因为你不需要内存使用量减少维护对子节点的引用。说明:这里我们将创建一个最大堆。首先创建一个insert方法,将元素添加到堆中。在插入期间,始终保持堆属性非常重要。对于最大堆,这意味着根元素应始终在树中具有最大值,并且所有父节点应该大于其子节点。对于堆的数组实现,这通常分三步完成:将新元素添加到数组的末尾。如果元素大于其父元素,请切换它们。继续切换,直到新元素小于其父元素或到达树的根。最后,添加一个print方法,该方法返回已添加到堆中的所有项的数组。
|
||||
Now we will move on to another tree data structure, the binary heap. A binary heap is a partially ordered binary tree which satisfies the heap property. The heap property specifies a relationship between parent and child nodes. You may have a max heap, in which all parent nodes are greater than or equal to their child nodes, or a min heap, in which the reverse is true. Binary heaps are also complete binary trees. This means that all levels of the tree are fully filled and if the last level is partially filled it is filled from left to right.
|
||||
|
||||
While binary heaps may be implemented as tree structures with nodes that contain left and right references, the partial ordering according to the heap property allows us to represent the heap with an array. The parent-children relationship is what we're interested in and with simple arithmetic we can compute the children of any parent and the parent of any child node.
|
||||
|
||||
For instance, consider this array representation of a binary min heap:
|
||||
|
||||
`[ 6, 22, 30, 37, 63, 48, 42, 76 ]`
|
||||
|
||||
The root node is the first element, `6`. Its children are `22` and `30`. If we look at the relationship between the array indices of these values, for index `i` the children are `2 * i + 1` and `2 * i + 2`. Similarly, the element at index `0` is the parent of these two children at indices `1` and `2`. More generally, we can find the parent of a node at any index with the following: `Math.floor((i - 1) / 2)`. These patterns will hold true as the binary tree grows to any size. Finally, we can make a slight adjustment to make this arithmetic even easier by skipping the first element in the array. Doing this creates the following relationship for any element at a given index `i`:
|
||||
|
||||
Example array representation:
|
||||
|
||||
`[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]`
|
||||
|
||||
An element's left child: `i * 2`
|
||||
|
||||
An element's right child: `i * 2 + 1`
|
||||
|
||||
An element's parent: `Math.floor(i / 2)`
|
||||
|
||||
Once you wrap your head around the math, using an array representation is very useful because node locations can be quickly determined with this arithmetic and memory usage is diminished because you don't need to maintain references to child nodes.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Instructions: Here we will create a max heap. Start by just creating an `insert` method which adds elements to our heap. During insertion, it is important to always maintain the heap property. For a max heap this means the root element should always have the greatest value in the tree and all parent nodes should be greater than their children. For an array implementation of a heap, this is typically accomplished in three steps:
|
||||
|
||||
<ol>
|
||||
<li>Add the new element to the end of the array.</li>
|
||||
<li>If the element is larger than its parent, switch them.</li>
|
||||
<li>Continue switching until the new element is either smaller than its parent or you reach the root of the tree.</li>
|
||||
</ol>
|
||||
|
||||
Finally, add a `print` method which returns an array of all the items that have been added to the heap.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在MaxHeap数据结构。
|
||||
The MaxHeap data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +58,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MaxHeap有一个名为insert的方法。
|
||||
MaxHeap should have a method called insert.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +74,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MaxHeap有一个名为print的方法。
|
||||
MaxHeap should have a method called print.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +90,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
insert方法根据max heap属性添加元素。
|
||||
The insert method should add elements according to the max heap property.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -87,7 +119,7 @@ assert(
|
||||
```js
|
||||
var MaxHeap = function() {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,18 +1,18 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c83
|
||||
title: 反转二叉树
|
||||
title: Invert a Binary Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301704
|
||||
dashedName: invert-a-binary-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
这里我们将创建一个反转二叉树的函数。给定二叉树,我们希望生成一个新树,它等效于该树的镜像。与原始树的inorder遍历相比,在倒置树上运行inorder遍历将以相反的顺序探索节点。在我们的二叉树上编写一个名为`invert`的方法。调用此方法应该反转当前树结构。理想情况下,我们希望在线性时间内就地执行此操作。也就是说,我们只访问每个节点一次,我们在不使用任何额外内存的情况下修改现有的树结构。祝你好运!
|
||||
Here will we create a function to invert a binary tree. Given a binary tree, we want to produce a new tree that is equivalently the mirror image of this tree. Running an inorder traversal on an inverted tree will explore the nodes in reverse order when compared to the inorder traversal of the original tree. Write a method to do this called `invert` on our binary tree. Calling this method should invert the current tree structure. Ideally, we would like to do this in-place in linear time. That is, we only visit each node once and we modify the existing tree structure as we go, without using any additional memory. Good luck!
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +26,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`invert`的方法。
|
||||
The binary search tree should have a method called `invert`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +42,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`invert`方法正确地反转树结构。
|
||||
The `invert` method should correctly invert the tree structure.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -70,7 +70,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
反转空树返回`null` 。
|
||||
Inverting an empty tree should return `null`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -160,7 +160,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,40 +1,50 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c5e
|
||||
title: 了解堆栈的工作原理
|
||||
title: Learn how a Stack Works
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301705
|
||||
dashedName: learn-how-a-stack-works
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
你可能熟悉桌子上的一摞书。您可能已使用文本编辑器的撤消功能。您也可能习惯按手机上的后退按钮返回应用中的上一个视图。你知道他们都有什么共同之处吗?它们都以某种方式存储数据,以便您可以向后遍历。堆栈中最顶层的书是最后放在那里的书。如果您从堆栈的顶部删除该书,则会显示在最后一本书之前放置的书籍,依此类推。如果你考虑一下,在上面的所有例子中,你都会获得<dfn>Last-In-First-Out</dfn>服务。我们将尝试使用我们的代码来模仿它。该数据存储方案称为<dfn>堆栈</dfn> 。特别是,我们必须实现将JavaScript对象推送到堆栈顶部的`push()`方法;和`pop()`方法,它删除当前位于堆栈顶部的JavaScript对象。
|
||||
You are probably familiar with stack of books on your table. You have likely used the undo feature of a text editor. You are also probably used to hitting the back button on your phone to go back to the previous view in your app.
|
||||
|
||||
You know what they all have in common? They all store the data in a way so that you can traverse backwards.
|
||||
|
||||
The topmost book in the stack was the one that was put there last. If you remove that book from your stack's top, you would expose the book that was put there before the last book and so on.
|
||||
|
||||
If you think about it, in all the above examples, you are getting <dfn>Last-In-First-Out</dfn> type of service. We will try to mimic this with our code.
|
||||
|
||||
This data storage scheme is called a <dfn>Stack</dfn>. In particular, we would have to implement the `push()` method that pushes JavaScript objects at the top of the stack; and `pop()` method, that removes the JavaScript object that's at the top of the stack at the current moment.
|
||||
|
||||
# --instructions--
|
||||
|
||||
这里我们有一堆作为数组表示的家庭作业: `"BIO12"`位于基础, `"PSY44"`位于堆栈的顶部。修改给定的数组,并使用上面提到的JavaScript方法将其视为`stack` 。从堆栈中删除顶部元素`"PSY44"` 。然后添加`"CS50"`作为堆栈的新顶部元素。
|
||||
Here we have a stack of homework assignments represented as an array: `"BIO12"` is at the base, and `"PSY44"` is at the top of the stack.
|
||||
|
||||
Modify the given array and treat it like a `stack` using the JavaScript methods mentioned above. Remove the top element `"PSY44"` from the stack. Then add `"CS50"` to be the new top element of the stack.
|
||||
|
||||
# --hints--
|
||||
|
||||
`homeworkStack`应该只包含4个元素。
|
||||
`homeworkStack` should only contain 4 elements.
|
||||
|
||||
```js
|
||||
assert(homeworkStack.length === 4);
|
||||
```
|
||||
|
||||
`homeworkStack`的最后一个元素应该是`"CS50"` 。
|
||||
The last element in `homeworkStack` should be `"CS50"`.
|
||||
|
||||
```js
|
||||
assert(homeworkStack[3] === 'CS50');
|
||||
```
|
||||
|
||||
`homeworkStack`不应包含`"PSY44"` 。
|
||||
`homeworkStack` should not contain `"PSY44"`.
|
||||
|
||||
```js
|
||||
assert(homeworkStack.indexOf('PSY44') === -1);
|
||||
```
|
||||
|
||||
不应更改`homeworkStack`的初始声明。
|
||||
The initial declaration of the `homeworkStack` should not be changed.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,20 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c6e
|
||||
title: 对两组数据执行差异
|
||||
title: Perform a Difference on Two Sets of Data
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301706
|
||||
dashedName: perform-a-difference-on-two-sets-of-data
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在本练习中,我们将对两组数据进行区分。我们将在我们的`Set`数据结构上创建一个名为`difference` 。集合的差异应比较两组并返回第一组中不存在的项目。此方法应将另一个`Set`作为参数,并返回两个集的`difference` 。例如,如果`setA = ['a','b','c']`和`setB = ['a','b','d','e']` ,则setA和setB的差异为: `setA.difference(setB) = ['c']` 。
|
||||
In this exercise we are going to perform a difference on 2 sets of data. We will create a method on our `Set` data structure called `difference`. A difference of sets should compare two sets and return the items present in the first set that are absent in the second. This method should take another `Set` as an argument and return the `difference` of the two sets.
|
||||
|
||||
For example, if `setA = ['a','b','c']` and `setB = ['a','b','d','e']`, then the difference of setA and setB is: `setA.difference(setB) = ['c']`.
|
||||
|
||||
# --hints--
|
||||
|
||||
你的`Set`类应该有一个`difference`方法。
|
||||
Your `Set` class should have a `difference` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +25,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
收回了适当的收藏
|
||||
Your `difference` method should return the proper collection.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -122,7 +124,7 @@ class Set {
|
||||
return newSet;
|
||||
}
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,29 +1,31 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c6f
|
||||
title: 对两组数据执行子集检查
|
||||
title: Perform a Subset Check on Two Sets of Data
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301707
|
||||
dashedName: perform-a-subset-check-on-two-sets-of-data
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在本练习中,我们将对2组数据执行子集测试。我们将在我们的`Set`数据结构上创建一个名为`subset` 。这将比较第一组与第二组,如果第一组完全包含在第二组中,则它将返回true。例如,如果`setA = ['a','b']`和`setB = ['a','b','c','d']` ,则setA和setB的子集为: `setA.subset(setB)`应该是`true` 。
|
||||
In this exercise, we are going to perform a subset test on 2 sets of data. We will create a method on our `Set` data structure called `isSubsetOf`. This will compare the first set against the second, and if the first set is fully contained within the second, it will return `true`.
|
||||
|
||||
For example, if `setA = ['a','b']` and `setB = ['a','b','c','d']`, then `setA` is a subset of `setB`, so `setA.isSubsetOf(setB)` should return `true`.
|
||||
|
||||
# --hints--
|
||||
|
||||
你的`Set`类应该有一个`union`方法。
|
||||
Your `Set` class should have a `isSubsetOf` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new Set();
|
||||
return typeof test.subset === 'function';
|
||||
return typeof test.isSubsetOf === 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
第一个Set()包含在第二个Set中
|
||||
The first Set() should be contained in the second Set
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -35,13 +37,13 @@ assert(
|
||||
setB.add('c');
|
||||
setB.add('a');
|
||||
setB.add('d');
|
||||
var subsetSetAB = setA.subset(setB);
|
||||
return subsetSetAB === true;
|
||||
var aIsSubsetOfB = setA.isSubsetOf(setB);
|
||||
return aIsSubsetOfB === true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`["a", "b"].subset(["a", "b", "c", "d"])`应该返回`true` “)
|
||||
`['a', 'b'].isSubsetOf(['a', 'b', 'c', 'd'])` should return `true`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -54,13 +56,13 @@ assert(
|
||||
setB.add('b');
|
||||
setB.add('c');
|
||||
setB.add('d');
|
||||
var subsetSetAB = setA.subset(setB);
|
||||
return subsetSetAB === true;
|
||||
var aIsSubsetOfB = setA.isSubsetOf(setB);
|
||||
return aIsSubsetOfB === true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`["a", "b", "c"].subset(["a", "b"])`应返回`false` “)
|
||||
`['a', 'b', 'c'].isSubsetOf(['a', 'b'])` should return `false`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -72,26 +74,26 @@ assert(
|
||||
setA.add('c');
|
||||
setB.add('a');
|
||||
setB.add('b');
|
||||
var subsetSetAB = setA.subset(setB);
|
||||
return subsetSetAB === false;
|
||||
var aIsSubsetOfB = setA.isSubsetOf(setB);
|
||||
return aIsSubsetOfB === false;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`[].subset([])`应该返回`true`
|
||||
`[].isSubsetOf([])` should return `true`
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var setA = new Set();
|
||||
var setB = new Set();
|
||||
var subsetSetAB = setA.subset(setB);
|
||||
return subsetSetAB === true;
|
||||
var aIsSubsetOfB = setA.isSubsetOf(setB);
|
||||
return aIsSubsetOfB === true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`["a", "b"].subset(["c", "d"])`应返回`false` “)
|
||||
`['a', 'b'].isSubsetOf(['c', 'd'])` should return `false`
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -102,8 +104,8 @@ assert(
|
||||
setA.add('b');
|
||||
setB.add('c');
|
||||
setB.add('d');
|
||||
var subsetSetAB = setA.subset(setB);
|
||||
return subsetSetAB === false;
|
||||
var aIsSubsetOfB = setA.isSubsetOf(setB);
|
||||
return aIsSubsetOfB === false;
|
||||
})()
|
||||
);
|
||||
```
|
||||
@ -198,7 +200,7 @@ class Set {
|
||||
return newSet;
|
||||
}
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,20 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6c
|
||||
title: 在两个集上执行联合
|
||||
title: Perform a Union on Two Sets
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301708
|
||||
dashedName: perform-a-union-on-two-sets
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在本练习中,我们将对两组数据执行联合。我们将在我们的`Set`数据结构上创建一个名为`union` 。此方法应将另一个`Set`作为参数,并返回两个集合的`union`集,不包括任何重复值。例如,如果`setA = ['a','b','c']`和`setB = ['a','b','d','e']` ,则setA和setB的并集为: `setA.union(setB) = ['a', 'b', 'c', 'd', 'e']` 。
|
||||
In this exercise we are going to perform a union on two sets of data. We will create a method on our `Set` data structure called `union`. This method should take another `Set` as an argument and return the `union` of the two sets, excluding any duplicate values.
|
||||
|
||||
For example, if `setA = ['a','b','c']` and `setB = ['a','b','d','e']`, then the union of setA and setB is: `setA.union(setB) = ['a', 'b', 'c', 'd', 'e']`.
|
||||
|
||||
# --hints--
|
||||
|
||||
你的`Set`类应该有一个`union`方法。
|
||||
Your `Set` class should have a `union` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +25,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
收回了适当的收藏
|
||||
The union of a Set containing values ["a", "b", "c"] and a Set containing values ["c", "d"] should return a new Set containing values ["a", "b", "c", "d"].
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -65,12 +67,12 @@ class Set {
|
||||
}
|
||||
// This method will return all the values in the set
|
||||
values() {
|
||||
return Object.keys(this.dictionary);
|
||||
return Object.values(this.dictionary);
|
||||
}
|
||||
// This method will add an element to the set
|
||||
add(element) {
|
||||
if (!this.has(element)) {
|
||||
this.dictionary[element] = true;
|
||||
this.dictionary[element] = element;
|
||||
this.length++;
|
||||
return true;
|
||||
}
|
||||
@ -111,12 +113,12 @@ class Set {
|
||||
}
|
||||
|
||||
values() {
|
||||
return Object.keys(this.dictionary);
|
||||
return Object.values(this.dictionary);
|
||||
}
|
||||
|
||||
add(element) {
|
||||
if (!this.has(element)) {
|
||||
this.dictionary[element] = true;
|
||||
this.dictionary[element] = element;
|
||||
this.length++;
|
||||
return true;
|
||||
}
|
||||
|
@ -1,18 +1,20 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6d
|
||||
title: 在两组数据上执行交集
|
||||
title: Perform an Intersection on Two Sets of Data
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301709
|
||||
dashedName: perform-an-intersection-on-two-sets-of-data
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在本练习中,我们将对两组数据执行交集。我们将在我们的`Set`数据结构上创建一个名为`intersection` 。集合的交集表示两个或更多集合共有的所有值。此方法应将另一个`Set`作为参数,并返回两个集合的`intersection` 。例如,如果`setA = ['a','b','c']`和`setB = ['a','b','d','e']` ,则setA和setB的交集为: `setA.intersection(setB) = ['a', 'b']` 。
|
||||
In this exercise we are going to perform an intersection on 2 sets of data. We will create a method on our `Set` data structure called `intersection`. An intersection of sets represents all values that are common to two or more sets. This method should take another `Set` as an argument and return the `intersection` of the two sets.
|
||||
|
||||
For example, if `setA = ['a','b','c']` and `setB = ['a','b','d','e']`, then the intersection of setA and setB is: `setA.intersection(setB) = ['a', 'b']`.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Set`类应该有一个`intersection`方法。
|
||||
Your `Set` class should have a `intersection` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -23,7 +25,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
收回了适当的收藏
|
||||
The proper collection should be returned.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -99,7 +101,7 @@ class Set {
|
||||
return newSet;
|
||||
}
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,28 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8b
|
||||
title: 从最大堆中删除元素
|
||||
title: Remove an Element from a Max Heap
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301710
|
||||
dashedName: remove-an-element-from-a-max-heap
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
现在我们可以向堆中添加元素,让我们看看如何删除元素。删除和插入元素都需要类似的逻辑。在最大堆中,您通常需要删除最大值,因此这只需要从树的根中提取它。这将破坏我们树的堆属性,因此我们必须以某种方式重新建立它。通常,对于最大堆,这可以通过以下方式完成:将堆中的最后一个元素移动到根位置。如果root的子节点大于它,则将root与较大值的子节点交换。继续交换,直到父级大于两个子级,或者到达树中的最后一级。说明:向我们的最大堆添加一个名为remove的方法。此方法应返回已添加到最大堆的最大值,并将其从堆中删除。它还应该重新排序堆,以便保持堆属性。删除元素后,堆中剩余的下一个最大元素应该成为根。此处再次添加插入方法。
|
||||
Now that we can add elements to our heap let's see how we can remove elements. Removing and inserting elements both require similar logic. In a max heap you will usually want to remove the greatest value, so this involves simply extracting it from the root of our tree. This will break the heap property of our tree, so we must reestablish it in some way. Typically, for a max heap this is done in the following way:
|
||||
|
||||
<ol>
|
||||
<li>Move the last element in the heap into the root position.</li>
|
||||
<li>If either child of the root is greater than it, swap the root with the child of greater value.</li>
|
||||
<li>Continue swapping until the parent is greater than both children or you reach the last level in the tree.</li>
|
||||
</ol>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Instructions: Add a method to our max heap called `remove`. This method should return the greatest value that has been added to our max heap and remove it from the heap. It should also reorder the heap so the heap property is maintained. After removing an element, the next greatest element remaining in the heap should become the root.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在MaxHeap数据结构。
|
||||
The MaxHeap data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +36,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MaxHeap有一个名为print的方法。
|
||||
MaxHeap should have a method called print.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +52,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MaxHeap有一个名为insert的方法。
|
||||
MaxHeap should have a method called insert.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +68,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
MaxHeap有一个名为remove的方法。
|
||||
MaxHeap should have a method called remove.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -74,7 +84,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
remove方法从最大堆中删除最大元素,同时保持最大堆属性。
|
||||
The remove method should remove the greatest element from the max heap while maintaining the max heap property.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,34 +1,41 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c65
|
||||
title: 按索引从链接列表中删除元素
|
||||
title: Remove Elements from a Linked List by Index
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301711
|
||||
dashedName: remove-elements-from-a-linked-list-by-index
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在我们继续讨论另一个数据结构之前,让我们先了解链接列表的最后几点练习。让我们编写一个`removeAt`方法,删除给定`index`处的`element` 。该方法应该称为`removeAt(index)` 。要删除某个`index`处的`element` ,我们需要在沿着链表移动时保持每个节点的运行计数。用于遍历链表的元素的常用技术涉及<dfn>“转轮”</dfn>或“哨兵”,它们“指向”代码所比较的节点。在我们的情况下,开始于`head`我们的名单中,我们先从一个`currentIndex`始于变量`0` 。对于我们传递的每个节点, `currentIndex`应该增加1。就像我们的`remove(element)`方法一样,当我们在removeAt(index)方法中删除节点时,我们需要注意不要孤立列表的其余部分。我们通过确保引用已删除节点的节点具有对下一节点的引用来保持节点连续。
|
||||
Before we move on to another data structure, let's get a couple of last bits of practice with linked lists.
|
||||
|
||||
Let's write a `removeAt` method that removes the `element` at a given `index`. The method should be called `removeAt(index)`. To remove an `element` at a certain `index`, we'll need to keep a running count of each node as we move along the linked list.
|
||||
|
||||
A common technique used to iterate through the elements of a linked list involves a <dfn>'runner'</dfn>, or sentinel, that 'points' at the nodes that your code is comparing. In our case, starting at the `head` of our list, we start with a `currentIndex` variable that starts at `0`. The `currentIndex` should increment by one for each node we pass.
|
||||
|
||||
Just like our `remove(element)` method, which [we covered in a previous lesson](/learn/coding-interview-prep/data-structures/remove-elements-from-a-linked-list), we need to be careful not to orphan the rest of our list when we remove the node in our `removeAt(index)` method. We keep our nodes contiguous by making sure that the node that has reference to the removed node has a reference to the next node.
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写`removeAt(index)`方法,删除并返回给定`index`处的节点。如果给定`index`为负数,或者大于或等于链表`length` ,则该方法应返回`null` 。注意请记住保持`currentIndex`计数。
|
||||
Write a `removeAt(index)` method that removes and returns a node at a given `index`. The method should return `null` if the given `index` is either negative, or greater than or equal to the `length` of the linked list.
|
||||
|
||||
**Note:** Remember to keep count of the `currentIndex`.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`LinkedList`类应该有一个`removeAt`方法。
|
||||
Your `LinkedList` class should have a `removeAt` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
return typeof test.removeAt === 'function';
|
||||
})(),
|
||||
'Your <code>LinkedList</code> class should have a <code>removeAt</code> method.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
您的`removeAt`方法应该减少链表的`length`
|
||||
Your `removeAt` method should reduce the `length` of the linked list by one.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -39,12 +46,43 @@ assert(
|
||||
test.add('kitten');
|
||||
test.removeAt(1);
|
||||
return test.size() === 2;
|
||||
})(),
|
||||
'Your <code>removeAt</code> method should reduce the <code>length</code> of the linked list'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
您的`removeAt`方法还应该返回已删除节点的元素。
|
||||
Your `removeAt` method should remove the element at the specified index from the linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
test.add('bird');
|
||||
test.removeAt(1);
|
||||
return (
|
||||
JSON.stringify(test.head()) ===
|
||||
'{"element":"cat","next":{"element":"kitten","next":{"element":"bird","next":null}}}'
|
||||
);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
When only one element is present in the linked list, your `removeAt` method should remove and return the element at specified index, and reduce the length of the linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
var removedItem = test.removeAt(0);
|
||||
return test.head() === null && test.size() === 0 && removedItem === 'cat';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `removeAt` method should return the element of the removed node.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -54,12 +92,11 @@ assert(
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.removeAt(1) === 'dog';
|
||||
})(),
|
||||
'Your <code>removeAt</code> method should also return the element of the removed node.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
如果给定索引小于`0`则`removeAt`方法也应返回`null`
|
||||
Your `removeAt` method should return `null` and the linked list should not change if the given index is less than `0`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -68,13 +105,17 @@ assert(
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.removeAt(-1) === null;
|
||||
})(),
|
||||
'Your <code>removeAt</code> method should also return <code>null</code> if the given index is less than <code>0</code>'
|
||||
var removedItem = test.removeAt(-1);
|
||||
return (
|
||||
removedItem === null &&
|
||||
JSON.stringify(test.head()) ===
|
||||
'{"element":"cat","next":{"element":"dog","next":{"element":"kitten","next":null}}}'
|
||||
);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
如果给定索引等于或大于链表的`length` ,则`removeAt`方法也应返回`null` 。
|
||||
Your `removeAt` method should return `null` and the linked list should not change if the given index is greater than or equal to the `length` of the list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -83,9 +124,13 @@ assert(
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.removeAt(3) === null;
|
||||
})(),
|
||||
'Your <code>removeAt</code> method should also return <code>null</code> if the given index is equal or more than the <code>length</code> of the linked list.'
|
||||
var removedItem = test.removeAt(3);
|
||||
return (
|
||||
removedItem === null &&
|
||||
JSON.stringify(test.head()) ===
|
||||
'{"element":"cat","next":{"element":"dog","next":{"element":"kitten","next":null}}}'
|
||||
);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
|
@ -1,34 +1,41 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c63
|
||||
title: 从链接列表中删除元素
|
||||
title: Remove Elements from a Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301712
|
||||
dashedName: remove-elements-from-a-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
链接列表的任何实现所需的下一个重要方法是`remove`方法。此方法应将要删除的元素作为参数,然后搜索列表以查找并删除包含该元素的节点。每当我们从链表中删除一个节点时,重要的是我们不要意外地孤立列表的其余部分。回想一下,每个节点的`next`属性都指向列表中跟随它的节点。如果我们删除中间元素,比如说,我们要确保我们从该元素的前一个节点的`next`属性到中间元素的`next`属性(这是列表中的下一个节点)的连接!这可能听起来真的很混乱,所以让我们回到康加线的例子,这样我们就有了一个很好的概念模型。想象自己在康加舞线上,直接在你面前的人离开了这条线。刚离开生产线的人不再将手放在任何人身上 - 而且你不再把手放在离开的人身上。你向前走,把你的手放在你看到的下一个人身上。如果我们要删除的元素是`head`元素,我们将`head`重新分配给链表的第二个节点。
|
||||
The next important method that any implementation of a linked list will need is a `remove` method. This method should take the element we want to remove as an argument, and then search the list to find and remove the node that contains that element.
|
||||
|
||||
Whenever we remove a node from a linked list, it's important that we don't accidentally orphan the rest of the list in doing so. Recall that every node's `next` property points to the node that follows it in the list. If we're removing the middle element, say, we'll want to make sure that we have a connection from that element's previous node's `next` property to the middle element's `next` property (which is the next node in the list!)
|
||||
|
||||
This might sound really confusing, so let's return to the conga line example so we have a good conceptual model. Picture yourself in a conga line, and the person directly in front of you leaves the line. The person who just left the line no longer has her hands on anyone in line--and you no longer have your hands on the person that left. You step forward and put your hands on next person you see.
|
||||
|
||||
If the element we wish to remove is the `head` element, we reassign the `head` to the second node of the linked list.
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写一个`remove`方法,该方法接受一个元素并将其从链表中删除。注意每次从链接列表中删除元素时,列表的`length`应减少一。
|
||||
Write a `remove` method that takes an element and removes it from the linked list.
|
||||
|
||||
**Note:** The `length` of the list should decrease by one every time an element is removed from the linked list.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`LinkedList`类应该有一个`remove`方法。
|
||||
Your `LinkedList` class should have a `remove` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
return typeof test.remove === 'function';
|
||||
})(),
|
||||
'Your <code>LinkedList</code> class should have a <code>remove</code> method.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`remove`第一个节点时, `remove`方法应重新分配`head`到第二个节点。
|
||||
Your `remove` method should reassign `head` to the second node when the first node is removed.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -38,12 +45,11 @@ assert(
|
||||
test.add('dog');
|
||||
test.remove('cat');
|
||||
return test.head().element === 'dog';
|
||||
})(),
|
||||
'Your <code>remove</code> method should reassign <code>head</code> to the second node when the first node is removed.'
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
对于每个删除的节点,您的`remove`方法应该将链表的`length`减少一个。
|
||||
Your `remove` method should decrease the `length` of the linked list by one for every node removed.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -51,14 +57,31 @@ assert(
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('hamster');
|
||||
test.remove('cat');
|
||||
return test.size() === 1;
|
||||
})(),
|
||||
'Your <code>remove</code> method should decrease the <code>length</code> of the linked list by one for every node removed.'
|
||||
test.remove('fish');
|
||||
return test.size() === 2;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
您的`remove`方法应该将已删除节点的上`next`节点的引用重新分配给已删除节点的`next`引用。
|
||||
Your `remove` method should reassign the reference of the previous node of the removed node to the removed node's `next` reference.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('snake');
|
||||
test.add('kitten');
|
||||
test.remove('snake');
|
||||
return test.head().next.next.element === 'kitten';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `remove` method should not change the linked list if the element does not exist in the linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -67,10 +90,12 @@ assert(
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
test.remove('dog');
|
||||
return test.head().next.element === 'kitten';
|
||||
})(),
|
||||
'Your <code>remove</code> method should reassign the reference of the previous node of the removed node to the removed node's <code>next</code> reference.'
|
||||
test.remove('elephant');
|
||||
return (
|
||||
JSON.stringify(test.head()) ===
|
||||
'{"element":"cat","next":{"element":"dog","next":{"element":"kitten","next":null}}}'
|
||||
);
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
@ -169,7 +194,7 @@ function LinkedList() {
|
||||
previous = currentNode;
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
|
||||
if (currentNode.next === null && currentNode.element !== element) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,27 +1,35 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c71
|
||||
title: 从ES6中的集中删除项目
|
||||
title: Remove items from a set in ES6
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301713
|
||||
dashedName: remove-items-from-a-set-in-es6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们使用`delete`方法练习从ES6集中`delete` 。首先,创建一个ES6 Set `var set = new Set([1,2,3]);`现在使用`delete`方法从Set中删除一个项目。
|
||||
Let's practice removing items from an ES6 Set using the `delete` method.
|
||||
|
||||
> set.delete(1);
|
||||
> console.log(\[... set])//应该返回\[2,3]
|
||||
>
|
||||
> >
|
||||
First, create an ES6 Set:
|
||||
|
||||
`var set = new Set([1,2,3]);`
|
||||
|
||||
Now remove an item from your Set with the `delete` method.
|
||||
|
||||
```js
|
||||
set.delete(1);
|
||||
console.log([...set]) // should return [ 2, 3 ]
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
现在,创建一个整数为1,2,3,4和5的集合。删除值2和5,然后返回集合。
|
||||
Now, create a set with the integers 1, 2, 3, 4, & 5.
|
||||
|
||||
Remove the values 2 and 5, and then return the set.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的集应包含值1,3和4
|
||||
Your Set should contain the values 1, 3, & 4
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,18 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c88
|
||||
title: 反转双重链接列表
|
||||
title: Reverse a Doubly Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301714
|
||||
dashedName: reverse-a-doubly-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们为我们的双向链表创建一个名为reverse的方法,它可以反转列表。一旦执行该方法,头部应指向前一个尾部,尾部应指向前一个头部。现在,如果我们从头到尾遍历列表,我们应该以与原始列表相反的顺序来满足节点。尝试反转空列表应返回null。
|
||||
Let's create one more method for our doubly linked list called reverse which reverses the list in place. Once the method is executed the head should point to the previous tail and the tail should point to the previous head. Now, if we traverse the list from head to tail we should meet the nodes in a reverse order compared to the original list. Trying to reverse an empty list should return null.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在DoublyLinkedList数据结构。
|
||||
The DoublyLinkedList data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,24 +26,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
DoublyLinkedList有一个名为add的方法。
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = false;
|
||||
if (typeof DoublyLinkedList !== 'undefined') {
|
||||
test = new DoublyLinkedList();
|
||||
}
|
||||
if (test.add == undefined) {
|
||||
return false;
|
||||
}
|
||||
return typeof test.add == 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
DoublyLinkedList有一个名为reverse的方法。
|
||||
The DoublyLinkedList should have a method called reverse.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -60,7 +43,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
反转空列表将返回null。
|
||||
Reversing an empty list should return null.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -74,7 +57,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
反向方法反转列表。
|
||||
The reverse method should reverse the list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -86,13 +69,15 @@ assert(
|
||||
test.add(58);
|
||||
test.add(61);
|
||||
test.add(32);
|
||||
test.add(95);
|
||||
test.add(41);
|
||||
test.reverse();
|
||||
return test.print().join('') == '326158';
|
||||
return test.print().join('') == '4195326158';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
当列表反转时,正确维护下一个和上一个引用。
|
||||
The next and previous references should be correctly maintained when a list is reversed.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -104,8 +89,10 @@ assert(
|
||||
test.add(11);
|
||||
test.add(22);
|
||||
test.add(33);
|
||||
test.add(44);
|
||||
test.add(55);
|
||||
test.reverse();
|
||||
return test.printReverse().join('') == '112233';
|
||||
return test.printReverse().join('') == '1122334455';
|
||||
})()
|
||||
);
|
||||
```
|
||||
@ -178,7 +165,7 @@ var DoublyLinkedList = function() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
```
|
||||
|
@ -1,22 +1,62 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c64
|
||||
title: 在链接列表中搜索
|
||||
title: Search within a Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301715
|
||||
dashedName: search-within-a-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们为链表类添加一些更有用的方法。如果我们可以判断我们的列表是否为空,那么它是否有用,就像我们的`Stack`和`Queue`类一样?我们还应该能够在链表中找到特定元素。遍历数据结构是你想要进行大量练习的东西!让我们创建一个`indexOf`方法,该方法将`element`作为参数,并在链表中返回该元素的`index` 。如果在链接列表中找不到该元素,则返回`-1` 。让我们实现一个相反的方法:一个`elementAt`方法,它将`index`作为参数并返回给定`index`处的`element` 。如果未找到任何`element` ,则返回`undefined` 。
|
||||
Let's add a few more useful methods to our linked list class. Wouldn't it be useful if we could tell if our list was empty or not, as with our `Stack` and `Queue` classes?
|
||||
|
||||
We should also be able to find specific elements in our linked list. Traversing through data structures is something you'll want to get a lot of practice with! Let's create an `indexOf` method that takes an `element` as an argument, and returns that element's `index` in the linked list. If the element is not found in the linked list, return `-1`.
|
||||
|
||||
Let's also implement a method that does the opposite: an `elementAt` method that takes an `index` as an argument and returns the `element` at the given `index`. If no `element` is found, return `undefined`.
|
||||
|
||||
# --instructions--
|
||||
|
||||
编写一个检查链表是否为空的`isEmpty`方法,返回给定元素`index`的`indexOf`方法,以及返回给定`index.`处`element`的`elementAt` `index.`
|
||||
Write an `isEmpty` method that checks if the linked list is empty, an `indexOf` method that returns the `index` of a given element, and an `elementAt` that returns an `element` at a given `index.`
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`LinkedList`类应该有一个`indexOf`方法。
|
||||
Your `LinkedList` class should have an `isEmpty` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
return typeof test.isEmpty === 'function';
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `isEmpty` method should return `false` when there is at least one element in linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.isEmpty() === false;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `isEmpty` method should return `true` when there are no elements in linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
return test.isEmpty() === true;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `LinkedList` class should have an `indexOf` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -27,7 +67,35 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`LinkedList`类应该有一个`elementAt`方法。
|
||||
Your `indexOf` method should return the index of a given element found in linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.indexOf('cat') === 0;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `indexOf` method should return `-1` if the given element is not found in linked list
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.indexOf('pony') === -1;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
Your `LinkedList` class should have an `elementAt` method.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -38,35 +106,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
您的`size`方法应返回链表的长度
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.size() === 3;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
`indexOf`方法应该返回给定元素的索引。
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.indexOf('kitten') === 2;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
您的`elementAt`方法应该返回给定索引处的元素。
|
||||
Your `elementAt` method should return the element found at a given index in linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -80,6 +120,20 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
Your `elementAt` method should return `undefined` if the given element is not found at a given index in linked list.
|
||||
|
||||
```js
|
||||
assert(
|
||||
(function () {
|
||||
var test = new LinkedList();
|
||||
test.add('cat');
|
||||
test.add('dog');
|
||||
test.add('kitten');
|
||||
return test.elementAt(5) === undefined;
|
||||
})()
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
@ -1,81 +1,75 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6a
|
||||
title: 键入的数组
|
||||
title: Typed Arrays
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301716
|
||||
dashedName: typed-arrays
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
数组是可以容纳许多不同元素的JavaScript对象。 `var complexArr = [1, 5, "2", "Word", {"name": "James"}];`基本上后台发生的事情是您的浏览器会自动为该阵列提供适当的内存空间。如果添加或删除数据,它也会根据需要进行更改。但是,在高性能和不同元素类型的世界中,有时您需要更具体地了解为阵列提供多少内存。 <dfn>类型化数组</dfn>是这个问题的答案。您现在可以说要为阵列提供多少内存。下面是可用的不同类型数组的基本概述,以及该数组中每个元素的大小(以字节为单位)。
|
||||
Arrays are JavaScript objects that can hold a lot of different elements.
|
||||
|
||||
| 类型 | 每个元素大小以字节为单位 |
|
||||
| ------------------- | ------------ |
|
||||
| `Int8Array` | 1 |
|
||||
| `Uint8Array` | 1 |
|
||||
| `Uint8ClampedArray` | 1 |
|
||||
| `Int16Array` | 2 |
|
||||
| `Uint16Array` | 2 |
|
||||
| `Int32Array` | 4 |
|
||||
| `Uint32Array` | 4 |
|
||||
| `Float32Array` | 4 |
|
||||
| `Float64Array` | 8 |
|
||||
`var complexArr = [1, 5, "2", "Word", {"name": "James"}];`
|
||||
|
||||
创建这种类型的数组有两种方法。一种方法是直接创建它。下面是如何创建一个3长度的`Int16Array` 。
|
||||
Basically what happens in the background is that your browser will automatically give the right amount of memory space for that array. It will also change as needed if you add or remove data.
|
||||
|
||||
> var i8 = new Int16Array(3);
|
||||
> 的console.log(I8);
|
||||
> //返回\[0,0,0]
|
||||
However, in the world of high performance and different element types, sometimes you need to be more specific on how much memory is given to an array.
|
||||
|
||||
您还可以创建一个
|
||||
<dfn>Typed arrays</dfn> are the answer to this problem. You are now able to say how much memory you want to give an array. Below is a basic overview of the different types of arrays available and the size in bytes for each element in that array.
|
||||
|
||||
<dfn>缓冲区</dfn>
|
||||
<table class='table table-striped'><tbody><tr><th>Type</th><th>Each element size in bytes</th></tr><tr><td><code>Int8Array</code></td><td>1</td></tr><tr><td><code>Uint8Array</code></td><td>1</td></tr><tr><td><code>Uint8ClampedArray</code></td><td>1</td></tr><tr><td><code>Int16Array</code></td><td>2</td></tr><tr><td><code>Uint16Array</code></td><td>2</td></tr><tr><td><code>Int32Array</code></td><td>4</td></tr><tr><td><code>Uint32Array</code></td><td>4</td></tr><tr><td><code>Float32Array</code></td><td>4</td></tr><tr><td><code>Float64Array</code></td><td>8</td></tr></tbody></table>
|
||||
|
||||
来分配您希望数组占用多少数据(以字节为单位)。 **注意**
|
||||
要使用缓冲区创建类型化数组,需要将字节数分配为上面列出的字节的倍数。
|
||||
There are two ways in creating these kind of arrays. One way is to create it directly. Below is how to create a 3 length `Int16Array`.
|
||||
|
||||
> //以不同方式创建相同的Int16Array数组
|
||||
> var byteSize = 6; //需要是2的倍数
|
||||
> var buffer = new ArrayBuffer(byteSize);
|
||||
> var i8View = new Int16Array(buffer);
|
||||
> buffer.byteLength; //返回6
|
||||
> i8View.byteLength; //返回6
|
||||
> 的console.log(i8View); //返回\[0,0,0]
|
||||
```js
|
||||
var i8 = new Int16Array(3);
|
||||
console.log(i8);
|
||||
// Returns [0, 0, 0]
|
||||
```
|
||||
|
||||
<dfn>缓冲区</dfn>
|
||||
You can also create a <dfn>buffer</dfn> to assign how much data (in bytes) you want the array to take up. **Note**
|
||||
To create typed arrays using buffers, you need to assign the number of bytes to be a multiple of the bytes listed above.
|
||||
|
||||
是仅承载数据的通用对象。您无法正常访问它们。要访问它们,您需要先创建一个
|
||||
```js
|
||||
// Create same Int16Array array differently
|
||||
var byteSize = 6; // Needs to be multiple of 2
|
||||
var buffer = new ArrayBuffer(byteSize);
|
||||
var i8View = new Int16Array(buffer);
|
||||
buffer.byteLength; // Returns 6
|
||||
i8View.byteLength; // Returns 6
|
||||
console.log(i8View); // Returns [0, 0, 0]
|
||||
```
|
||||
|
||||
<dfn>视图</dfn>
|
||||
<dfn>Buffers</dfn> are general purpose objects that just carry data. You cannot access them normally. To access them, you need to first create a <dfn>view</dfn>.
|
||||
|
||||
。
|
||||
```js
|
||||
i8View[0] = 42;
|
||||
console.log(i8View); // Returns [42, 0, 0]
|
||||
```
|
||||
|
||||
> i8View \[0] = 42;
|
||||
> 的console.log(i8View); //返回\[42,0,0]
|
||||
|
||||
**注意**
|
||||
类型化数组没有传统数组所具有的某些方法,如`.pop()`或`.push()` 。类型化数组也会失败`Array.isArray()` ,它会检查某些内容是否为数组。虽然更简单,但对于不太复杂的JavaScript引擎来说,这可能是一个优势。
|
||||
**Note**
|
||||
Typed arrays do not have some of the methods traditional arrays have such as `.pop()` or `.push()`. Typed arrays also fail `Array.isArray()` that checks if something is an array. Although simpler, this can be an advantage for less-sophisticated JavaScript engines to implement them.
|
||||
|
||||
# --instructions--
|
||||
|
||||
首先创建一个64字节的`buffer` 。然后创建一个`Int32Array`类型数组,其中包含一个名为`i32View`的视图。
|
||||
First create a `buffer` that is 64-bytes. Then create a `Int32Array` typed array with a view of it called `i32View`.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`buffer`应该是64字节大。
|
||||
Your `buffer` should be 64 bytes large.
|
||||
|
||||
```js
|
||||
assert(buffer.byteLength === 64);
|
||||
```
|
||||
|
||||
您的缓冲区的`i32View`视图应该是64字节大。
|
||||
Your `i32View` view of your buffer should be 64 bytes large.
|
||||
|
||||
```js
|
||||
assert(i32View.byteLength === 64);
|
||||
```
|
||||
|
||||
您的缓冲区的`i32View`视图应为16个元素长。
|
||||
Your `i32View` view of your buffer should be 16 elements long.
|
||||
|
||||
```js
|
||||
assert(i32View.length === 16);
|
||||
|
@ -1,22 +1,34 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c72
|
||||
title: 在ES6集上使用.has和.size
|
||||
title: Use .has and .size on an ES6 Set
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301717
|
||||
dashedName: use--has-and--size-on-an-es6-set
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
让我们看一下ES6 Set对象上可用的.has和.size方法。首先,创建一个ES6 Set `var set = new Set([1,2,3]);` .has方法将检查该值是否包含在集合中。 `var hasTwo = set.has(2);` .size方法将返回一个表示Set `var howBig = set.size;`大小的整数`var howBig = set.size;`
|
||||
Let's look at the .has and .size methods available on the ES6 Set object.
|
||||
|
||||
First, create an ES6 Set
|
||||
|
||||
`var set = new Set([1,2,3]);`
|
||||
|
||||
The .has method will check if the value is contained within the set.
|
||||
|
||||
`var hasTwo = set.has(2);`
|
||||
|
||||
The .size method will return an integer representing the size of the Set
|
||||
|
||||
`var howBig = set.size;`
|
||||
|
||||
# --instructions--
|
||||
|
||||
在本练习中,我们将数组和值传递给checkSet()函数。您的函数应该从数组参数创建ES6集。查找该集是否包含value参数。找到集合的大小。并在数组中返回这两个值。
|
||||
In this exercise we will pass an array and a value to the checkSet() function. Your function should create an ES6 set from the array argument. Find if the set contains the value argument. Find the size of the set. And return those two values in an array.
|
||||
|
||||
# --hints--
|
||||
|
||||
`checkSet([4, 5, 6], 3)`应该返回[false,3]
|
||||
`checkSet([4, 5, 6], 3)` should return [ false, 3 ]
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,18 +1,24 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c7f
|
||||
title: 在二叉搜索树中使用广度优先搜索
|
||||
title: Use Breadth First Search in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301718
|
||||
dashedName: use-breadth-first-search-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
这里我们将介绍另一种树遍历方法:广度优先搜索。与上一次挑战中的深度优先搜索方法相比,广度优先搜索在继续进入下一级别之前探索树中给定级别中的所有节点。通常,队列在广度优先搜索算法的设计中用作辅助数据结构。在此方法中,我们首先将根节点添加到队列中。然后我们开始一个循环,我们将队列中的第一个项目出列,将其添加到一个新数组,然后检查它们的子子树。如果它的孩子不是空的,他们每个都被排队。此过程将继续,直到队列为空。说明:让我们在树中创建一个名为`levelOrder`的广度优先搜索方法。此方法应返回一个包含所有树节点值的数组,并以广度优先的方式进行探索。确保返回数组中的值,而不是节点本身。应从左到右遍历一个级别。接下来,让我们编写一个名为`reverseLevelOrder`的类似方法,它在每个级别执行相同的搜索,但是反向(从右到左)。
|
||||
Here we will introduce another tree traversal method: breadth-first search. In contrast to the depth-first search methods from the last challenge, breadth-first search explores all the nodes in a given level within a tree before continuing on to the next level. Typically, queues are utilized as helper data structures in the design of breadth-first search algorithms.
|
||||
|
||||
In this method, we start by adding the root node to a queue. Then we begin a loop where we dequeue the first item in the queue, add it to a new array, and then inspect both its child subtrees. If its children are not null, they are each enqueued. This process continues until the queue is empty.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Let's create a breadth-first search method in our tree called `levelOrder`. This method should return an array containing the values of all the tree nodes, explored in a breadth-first manner. Be sure to return the values in the array, not the nodes themselves. A level should be traversed from left to right. Next, let's write a similar method called `reverseLevelOrder` which performs the same search but in the reverse direction (right to left) at each level.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +32,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`levelOrder`的方法。
|
||||
The binary search tree should have a method called `levelOrder`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +48,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`reverseLevelOrder`的方法。
|
||||
The binary search tree should have a method called `reverseLevelOrder`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +64,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`levelOrder`方法返回按级别顺序探索的树节点值的数组。
|
||||
The `levelOrder` method should return an array of the tree node values explored in level order.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -88,7 +94,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`reverseLevelOrder`方法返回以反向级别顺序探索的树节点值的数组。
|
||||
The `reverseLevelOrder` method should return an array of the tree node values explored in reverse level order.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -118,7 +124,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`levelOrder`方法为空树返回`null` 。
|
||||
The `levelOrder` method should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -137,7 +143,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`reverseLevelOrder`方法为空树返回`null` 。
|
||||
The `reverseLevelOrder` method should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -208,7 +214,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,18 +1,22 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7e
|
||||
title: 在二叉搜索树中使用深度优先搜索
|
||||
title: Use Depth First Search in a Binary Search Tree
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301719
|
||||
dashedName: use-depth-first-search-in-a-binary-search-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
我们知道如何在二叉搜索树中搜索特定值。但是,如果我们只想探索整棵树呢?或者,如果我们没有有序树,我们只需要搜索一个值?这里我们将介绍一些可用于探索树数据结构的树遍历方法。首先是深度优先搜索。在深度优先搜索中,在搜索继续到另一个子树之前,尽可能深地探索给定子树。有三种方法可以完成:按顺序:从最左边的节点开始搜索,到最右边的节点结束。预购:在树叶前探索所有的根。下订单:在根之前探索所有的叶子。您可能会猜到,您可以选择不同的搜索方法,具体取决于树存储的数据类型以及您要查找的内容。对于二叉搜索树,inorder遍历以排序顺序返回节点。说明:这里我们将在二叉搜索树上创建这三种搜索方法。深度优先搜索是一种固有的递归操作,只要子节点存在,它就会继续探索更多的子树。一旦理解了这个基本概念,您就可以简单地重新排列探索节点和子树的顺序,以生成上述三个搜索中的任何一个。例如,在后序搜索中,我们希望在开始返回任何节点本身之前一直递归到叶节点,而在预订搜索中,我们希望首先返回节点,然后继续递归在树下。在我们的树上定义`inorder` , `preorder`和`postorder`方法。这些方法中的每一个都应该返回表示树遍历的项数组。确保返回数组中每个节点的整数值,而不是节点本身。最后,如果树为空,则返回`null` 。
|
||||
We know how to search a binary search tree for a specific value. But what if we just want to explore the entire tree? Or what if we don't have an ordered tree and we need to just search for a value? Here we will introduce some tree traversal methods which can be used to explore tree data structures. First up is depth-first search. In depth-first search, a given subtree is explored as deeply as possible before the search continues on to another subtree. There are three ways this can be done: In-order: Begin the search at the left-most node and end at the right-most node. Pre-order: Explore all the roots before the leaves. Post-order: Explore all the leaves before the roots. As you may guess, you may choose different search methods depending on what type of data your tree is storing and what you are looking for. For a binary search tree, an inorder traversal returns the nodes in sorted order.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Here we will create these three search methods on our binary search tree. Depth-first search is an inherently recursive operation which continues to explore further subtrees so long as child nodes are present. Once you understand this basic concept, you can simply rearrange the order in which you explore the nodes and subtrees to produce any of the three searches above. For example, in post-order search we would want to recurse all the way to a leaf node before we begin to return any of the nodes themselves, whereas in pre-order search we would want to return the nodes first, and then continue recursing down the tree. Define `inorder`, `preorder`, and `postorder` methods on our tree. Each of these methods should return an array of items which represent the tree traversal. Be sure to return the integer values at each node in the array, not the nodes themselves. Finally, return `null` if the tree is empty.
|
||||
|
||||
# --hints--
|
||||
|
||||
存在`BinarySearchTree`数据结构。
|
||||
The `BinarySearchTree` data structure should exist.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -26,7 +30,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`inorder`的方法。
|
||||
The binary search tree should have a method called `inorder`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -42,7 +46,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`preorder`的方法。
|
||||
The binary search tree should have a method called `preorder`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -58,7 +62,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
二叉搜索树有一个名为`postorder`的方法。
|
||||
The binary search tree should have a method called `postorder`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -74,7 +78,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`inorder`方法返回由inorder遍历产生的节点值数组。
|
||||
The `inorder` method should return an array of the node values that result from an inorder traversal.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -104,7 +108,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`preorder`方法返回由前序遍历产生的节点值数组。
|
||||
The `preorder` method should return an array of the node values that result from a preorder traversal.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -134,7 +138,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`postorder`方法返回由后序遍历产生的节点值数组。
|
||||
The `postorder` method should return an array of the node values that result from a postorder traversal.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -164,7 +168,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`inorder`方法为空树返回`null` 。
|
||||
The `inorder` method should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -183,7 +187,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`preorder`方法为空树返回`null` 。
|
||||
The `preorder` method should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -202,7 +206,7 @@ assert(
|
||||
);
|
||||
```
|
||||
|
||||
`postorder`方法为空树返回`null` 。
|
||||
The `postorder` method should return `null` for an empty tree.
|
||||
|
||||
```js
|
||||
assert(
|
||||
@ -274,7 +278,7 @@ function Node(value) {
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
@ -1,26 +1,34 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c73
|
||||
title: 使用Spread和Notes进行ES5 Set()集成
|
||||
title: Use Spread and Notes for ES5 Set() Integration
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301720
|
||||
dashedName: use-spread-and-notes-for-es5-set-integration
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
你还记得ES6传播运营商`...` ? `...`可以在ES6中获取可迭代对象并将它们转换为数组。让我们创建一个Set,并检查传播函数。
|
||||
Do you remember the ES6 spread operator `...`?
|
||||
|
||||
> var set = new Set(\[1,2,3]);
|
||||
> var setToArr = \[... set]
|
||||
> console.log(setToArr)//返回\[1,2,3]
|
||||
`...` can take iterable objects in ES6 and turn them into arrays.
|
||||
|
||||
Let's create a Set, and check out the spread function.
|
||||
|
||||
```js
|
||||
var set = new Set([1,2,3]);
|
||||
var setToArr = [...set]
|
||||
console.log(setToArr) // returns [ 1, 2, 3 ]
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
在本练习中,我们将set对象传递给`checkSet`函数。它应该返回一个包含Set值的数组。现在你已经成功学会了如何使用ES6 `Set()`对象,干得好!
|
||||
In this exercise we will pass a set object to the `checkSet` function. It should return an array containing the values of the Set.
|
||||
|
||||
Now you've successfully learned how to use the ES6 `Set()` object, good job!
|
||||
|
||||
# --hints--
|
||||
|
||||
您的套装已正确退回!
|
||||
`checkSet(new Set([1,2,3,4,5,6,7])` should return `[1, 2, 3, 4, 5, 6, 7]`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
|
@ -1,28 +1,32 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c61
|
||||
title: 使用链接列表中的节点
|
||||
title: Work with Nodes in a Linked List
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301721
|
||||
dashedName: work-with-nodes-in-a-linked-list
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
您将在计算机科学中遇到的另一个常见数据结构是<dfn>链表</dfn> 。链表是数据元素的线性集合,称为“节点”,每个数据元素指向下一个。链表中的每个<dfn>节点都</dfn>包含两个关键信息: `element`本身和对下一个`node`的引用。想象一下你在康加舞线上。你的手掌握在线下的下一个人身上,你身后的人就会抓住你。你可以直接看到这个人,但是他们阻挡了前方其他人的视线。一个节点就像一个康加舞线上的人:他们知道自己是谁,他们只能看到下一个人,但他们并不知道前方或后方的其他人。
|
||||
Another common data structure you'll run into in computer science is the <dfn>linked list</dfn>. A linked list is a linear collection of data elements, called 'nodes', each of which points to the next. Each <dfn>node</dfn> in a linked list contains two key pieces of information: the `element` itself, and a reference to the next `node`.
|
||||
|
||||
Imagine that you are in a conga line. You have your hands on the next person in the line, and the person behind you has their hands on you. You can see the person straight ahead of you, but they are blocking the view of the other people ahead in line. A node is just like a person in a conga line: they know who they are and they can only see the next person in line, but they are not aware of the other people ahead or behind them.
|
||||
|
||||
# --instructions--
|
||||
|
||||
在我们的代码编辑器中,我们创建了两个节点, `Kitten`和`Puppy` ,我们手动将`Kitten`节点连接到`Puppy`节点。创建`Cat`和`Dog`节点并手动将它们添加到该行。
|
||||
In our code editor, we've created two nodes, `Kitten` and `Puppy`, and we've manually connected the `Kitten` node to the `Puppy` node.
|
||||
|
||||
Create a `Cat` and `Dog` node and manually add them to the line.
|
||||
|
||||
# --hints--
|
||||
|
||||
您的`Puppy`节点应该具有对`Cat`节点的引用。
|
||||
Your `Puppy` node should have a reference to a `Cat` node.
|
||||
|
||||
```js
|
||||
assert(Puppy.next.element === 'Cat');
|
||||
```
|
||||
|
||||
您的`Cat`节点应该具有对`Dog`节点的引用。
|
||||
Your `Cat` node should have a reference to a `Dog` node.
|
||||
|
||||
```js
|
||||
assert(Cat.next.element === 'Dog');
|
||||
|
Reference in New Issue
Block a user