链表 python 面试题
by Anthony Sistilli
安东尼·西斯蒂里(Anthony Sistilli)
I always understood the core concept of Linked Lists, but I never put it into practice.
我一直很了解链表的核心概念,但是我从未付诸实践。
It wasn’t until my very first Amazon interview years ago when I realized that I had no idea how the concept of Linked Lists translated into code.
直到几年前我第一次接受亚马逊采访时,我才意识到我不知道链接列表的概念如何转化为代码。
And that’s why I’m writing this guide!
这就是为什么我要编写本指南!
My goal is to help you get a job as a Software Engineer.
我的目标是帮助您找到一名软件工程师。
I want to cover a lot of Linked Lists interview questions, and this article is the first step in that process. So let’s dive in.
我想介绍很多“链接列表”采访问题,而本文是该过程的第一步。 因此,让我们开始吧。
A Linked List is a data structure that consists of many mini-data structures called ‘Nodes.’ The Nodes link together to form a list.
链表是一种数据结构,由许多称为“节点”的小型数据结构组成。 节点链接在一起形成一个列表。
The ‘Head Node’: The head node is simply the first node in the linked list. As we can see from the example above, the node containing ‘5’ is the first node, and therefore the head.
“头节点”:头节点只是链表中的第一个节点。 从上面的示例可以看出,包含“ 5”的节点是第一个节点,因此是头。
The ‘Tail Node’: The tail node is the last node in the sequence. Since it’s the last node, it points to null, because there is no next node in the sequence. In the example above, the node containing ‘3’ would be the tail node.
“尾节点”:尾节点是序列中的最后一个节点。 由于它是最后一个节点,因此它指向null,因为序列中没有下一个节点。 在上面的示例中,包含“ 3”的节点将是尾节点。
When it comes to Linked Lists, there are two main kinds.
当涉及到链表时,主要有两种。
Those that are ‘singly’ linked, and those that are ‘doubly’ linked.
“单”链接的那些和“双”链接的那些。
Singly linked means that each node only points to at most 1 other node, the node in front of it. This is exhibited in the example above.
单链接意味着每个节点最多仅指向另一个节点,即它前面的节点。 在上面的示例中展示了这一点。
Doubly linked means that each node can point to 2 other nodes, the node in front of it and the node behind it. As we can see from the example below, since there is no node preceding the head node (which is 5), one of its pointers points to null.
双链接意味着每个节点都可以指向另外2个节点,即它前面的节点和它后面的节点。 从下面的示例中可以看到,由于头节点之前没有节点(为5),因此其指针之一指向null。
Coding Linked Lists can be a 4 line problem or a 400 line problem. It depends on how you want to approach it.
编码链接列表可能是4行问题或400行问题。 这取决于您要如何处理它。
On the simplest level, like we discussed, a linked list is just a bunch of connected nodes.
在最简单的层次上,如我们所讨论的,链表只是一堆连接的节点。
Thus, all we really need to create this structure is a node object.
因此,我们真正需要创建此结构的只是一个节点对象。
class linkedListNode: def __init__(self, value, nextNode=None): self.value = value self.nextNode = nextNode
Here we can see we’ve simply created a class that has a value and nextNode attribute.
在这里,我们可以看到我们仅创建了一个具有值和nextNode属性的类。
To create a node, we simply pass in a value.
要创建节点,我们只需传递一个值即可。
node1 = linkedListNode("3") # "3"node2 = linkedListNode("7") # "7"node3 = linkedListNode("10") # "10"
Here, we’ve created 3 individual nodes.
在这里,我们创建了3个单独的节点。
The next step is simply to connect them together.
下一步就是将它们连接在一起。
node1.nextNode = node2 node2.nextNode = node3
The first line above makes node1 point to node2:
上面的第一行使node1指向node2:
“3” →“7”
“ 3”→“ 7”
The second line above makes node2 point to node3:
上面的第二行使node2指向node3:
“7”→”10"
“ 7”→“ 10”
All together, we’re left with a Linked List that looks like this:
总之,我们剩下的链接列表如下所示:
“3”→”7"→”10"→Null
“ 3”→“ 7”→“ 10”→空
Note: “10” points to null, because there was no nextNode assigned to node3, and the default nextNode is Null.
注意:“ 10”指向null,因为没有将nextNode分配给node3,默认的nextNode为Null。
Like I mentioned earlier, there are a lot of different ways to do this. This is just the simplest.
就像我之前提到的,有很多不同的方法可以做到这一点。 这是最简单的。
If you are trying to make an entire LinkedList class, this video goes in depth on how to do that.
如果您要制作整个LinkedList类,则此视频深入介绍了如何执行此操作。
If you’re doing a programming interview, and you get asked a Linked List question, you’re not going to be given all the nodes.
如果您正在进行编程面试,并且被问到“链表”问题,那么您将不会获得所有节点。
All you’ll get is the head node.
您将获得的只是头节点。
From that head node, you have to get the rest of the list.
从该头节点,您必须获取列表的其余部分。
First let’s understand how to get the value and nextNode from a node in Python.
首先,让我们了解如何从Python中的节点获取值和nextNode。
Let’s say we have a node simply named ‘node’.
假设我们有一个名为“ node”的节点。
Getting the value of the node:
获取节点的值:
node.value
Getting the nextNode of the node:
获取节点的nextNode:
node.nextNode
This first thing we want to do is create a variable called “currentNode” that keeps track of the node we’re at. We want to assign this to our head node at first.
我们要做的第一件事是创建一个名为“ currentNode”的变量,以跟踪我们所在的节点。 我们首先要将此分配给我们的头节点。
currentNode = head
Now all we have to do is simply check whether or not our current node is Null. If it’s not, we make our ‘currentNode’ equal to the ‘nextNode’ of the ‘currentNode’.
现在,我们要做的就是简单地检查当前节点是否为Null。 如果不是,则使“ currentNode”等于“ currentNode”的“ nextNode”。
currentNode = node1while currentNode is not None: currentNode = currentNode.nextNode
Let’s say we have the following Linked List: “3”→”7"→”10".
假设我们有以下链接列表:“ 3”→“ 7”→“ 10”。
Our head and first ‘currentNode’ is “3”.
我们的头和第一个“ currentNode”是“ 3”。
When we do
当我们做
currentNode = currentNode.nextNode
We are reassigning ‘currentNode’ to our current node’s neighbor, which in this case is “7”.
我们正在将“ currentNode”重新分配给当前节点的邻居,在本例中为“ 7”。
This continues until the currentNode is pointed to None, in which case the loop stops.
这一直持续到currentNode指向None为止,在这种情况下,循环停止。
And that is the basic way to traverse through a Linked List in Python.
这是遍历Python中的链表的基本方法。
Link to the code on Github.
链接到Github上的代码。
When you insert an element into a linked list, you insert it into the back unless specified otherwise.
将元素插入到链表中时,除非另有说明,否则将其插入到后面。
Let’s use the following example:
让我们使用以下示例:
“3”→”7"→”10"→Null
“ 3”→“ 7”→“ 10”→空
Let’s say we want to insert a “4”.
假设我们要插入“ 4”。
We would simply find the tail node, in this case “10”, and set its nextNode to our “4” node.
我们将简单地找到尾节点,在本例中为“ 10”,并将其nextNode设置为“ 4”节点。
“3”→”7"→”10"→“4”→Null
“ 3”→“ 7”→“ 10”→“ 4”→空
node4 = linkedListNode("4")node3.nextNode = node4
Now let’s say we were in an interview, and all we had was the head node.
现在假设我们正在接受采访,而我们所拥有的只是头节点。
We simply traverse through the LinkedList to find the tail. Once we have the tail, we simply set its nextNode to our new node that we create.
我们只需遍历LinkedList即可找到尾部。 一旦有了尾巴,我们只需将其nextNode设置为我们创建的新节点即可。
def insertNode(head, valuetoInsert): currentNode = head while currentNode is not None: if currentNode.nextNode is None: currentNode.nextNode = linkedListNode(valuetoInsert) return head currentNode = currentNode.nextNode
Deleting can get a bit tricky.
删除可能会有些棘手。
Let’s take the same example.
让我们以同样的例子。
“3”→”7"→”10"→Null
“ 3”→“ 7”→“ 10”→空
If we wanted to delete the “7”, all we need to do is point the “3” to the “10” so that the “7” is never referenced.
如果要删除“ 7”,我们要做的就是将“ 3”指向“ 10”,这样就永远不会引用“ 7”。
“3”→”10"→Null
“ 3”→“ 10”→空
To do this, we would have to traverse the list while not only keeping track of the currentNode, but also keeping track of the previousNode.
为此,我们必须遍历列表,不仅要跟踪currentNode,还要跟踪previousNode。
We would also have to account for the head node being the node we want to delete.
我们还必须考虑头节点是我们要删除的节点。
In the code below, we simply delete the first instance of the value we want to delete.
在下面的代码中,我们仅删除要删除的值的第一个实例。
Note that there are many ways to accomplish this, and the solution below might not be the cleanest code you’ll see in your life. However, in the heat of an interview, the interviewer probably won’t expect textbook perfect code.
请注意,有许多方法可以完成此操作,并且下面的解决方案可能不是您一生中看到的最干净的代码。 但是,在面试时,面试官可能不会期望教科书上有完美的代码。
def deleteNode(head, valueToDelete): currentNode = head previousNode = None while currentNode is not None: if currentNode.value == valueToDelete: if previousNode is None: newHead = currentNode.nextNode currentNode.nextNode = None return newHead # Deleted the head previousNode.nextNode = currentNode.nextNode return head previousNode = currentNode currentNode = currentNode.nextNode return head # Value to delete was not found.
In the code above, once we find the node we want to delete, we set the previous node’s “nextNode” to the deleted node’s “nextNode” to completely cut it out of the list.
在上面的代码中,一旦找到要删除的节点,就将前一个节点的“ nextNode”设置为已删除节点的“ nextNode”,以将其完全从列表中删除。
**NOTE** These are the time complexities for the node structure above, which is most likely to appear on an interview. In practical cases, you can store attributes in a LinkedList class to lower these complexities.
**注意**这些是以上节点结构的时间复杂性,最有可能出现在采访中。 在实际情况下,可以将属性存储在LinkedList类中以降低这些复杂性。
‘n’ = the amount of elements inside the Linked List.
'n'=链表中元素的数量。
Inserting to the back of the Linked List— We go through all n elements to find the tail and insert our new node. O(n)
在链接列表的后面插入-我们遍历所有n个元素以找到尾部并插入新节点。 上)
Inserting to the front of the Linked List — We simply create the new node and set its nextNode to the head. No need to traverse the list. O(1)
插入到链表的最前面—我们只需创建新节点并将其nextNode设置为最前面。 无需遍历列表。 O(1)
Traversing — We go through all n elements once. O(n)
遍历—我们遍历所有n个元素。 上)
Deleting — Worst case scenario, the node we’re deleting is the last node, causing us to traverse through the entire list. O(n)
删除-最坏的情况是,我们要删除的节点是最后一个节点,导致我们遍历整个列表。 上)
You now have the fundamental knowledge you need to start tackling Linked List interview questions!
现在,您已经具备了开始处理链接列表面试问题所需的基本知识!
They can start off easy, and get tough really quick.
他们可以轻松开始,很快就能变得坚强。
In the next article, I’m going to go over a couple of common questions and techniques you can use to solve them.
在下一篇文章中,我将介绍一些可以用来解决这些问题的常见问题和技巧。
If you’re a student looking to land your dream internship or full-time job within the next 2 years, start practicing now!
如果您是希望在未来两年内获得理想实习或全职工作的学生,请立即开始练习!
I’ve started a community (www.theforge.ca) where we connect students with mentors and industry experts that help them navigate their way to their dream job.
我已经建立了一个社区( www.theforge.ca ),在这里我们将学生与导师和行业专家联系起来,以帮助他们顺利完成自己的梦想工作。
Thanks for reading, and good luck!
感谢您的阅读,祝您好运!
翻译自: https://www.freecodecamp.org/news/python-interview-question-guide-how-to-code-a-linked-list-fd77cbbd367d/
链表 python 面试题