一、写在前面
反转单链表是一个非常经典的算法题,也是很多大厂喜欢考察的一个问题。下面介绍一下剑指上反转单链表问题的实现过程,附上一个类似的同样考察单链表的校招题目。(题目来自牛客网)今日份题目完成啦
二、题目一(剑指题)
1 题目描述
输入一个链表,反转链表后,输出新链表的表头。
2 算法步骤
(1)由于需要对整个单链表进行反转,所以在最外层构建一个while循环,用来遍历所有结点。
(2)定义一个node,用来存放反转后的单链表的单个结点。定义一个newHead结点,作为反转后的单链表的头结点,刚开始初始化为NULL,是因为当链表长度为0时,相当于此时的链表头结点为NULL。
(3)在while循环中,首先将反转前的pHead结点传给node(node=pHead),当前结点值已经得到,再执行pHead=pHead->next让pHead指向下一个结点。之后执行node->next=newHead,让node的下一个结点指向newHead(也就是反转后的链表的头结点),此时就已经将当前结点链接到反转后的单链表上了。最后通过 newHead=node让反转后的单链表的头结点更新为当前的node结点。
(4)while循环结束也意味着反转前单链表的所有结点都已经反向链接到新的链表中。由于题目要求最后返回反转后的单链表的新的表头,所以return newHead进行返回。
3 通过的代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode*node;
ListNode*newHead=NULL;
while(pHead!=NULL)
{
node=pHead;
pHead=pHead->next;
node->next=newHead;
newHead=node;
}
return newHead;
}
};
三、题目二(小米秋招题)
1 题目描述
找出单向链表中的一个节点,该节点到尾指针的距离为K。链表的倒数第0个结点为链表的尾指针。要求时间复杂度为O(n)。
链表结点定义如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
}
链表节点的值初始化为1,2,3,4,5,6,7。
输入描述:该节点到尾指针的距离K
输出描述:返回该单向链表的倒数第K个节点,输出节点的值
备注:请自觉实现一个链表,将1到7依次加入链表,然后再寻找倒数第K个节点。要求加节点与找节点的操作复杂度均为O(n)。
2 算法步骤
创建单链表也就是CreateList函数是单链表中十分基础的内容,必须要掌握的。这里不做赘述。
找出单向链表的倒数第K个节点,首先明确算法的思想是,我定义两个结点,先让这两个结点之间相隔K-1(也可以是K,看个人理解)的距离,然后两个结点同时开始往后跑,直到其中一个结点到达了链表的最后一个结点位置,此时另一个结点就是我们需要得到的,也就是单向链表的倒数第K个节点。
算法步骤如下:
(1)首先定义两个结点p和q,都指向链表的头结点pHead。
(2)while(n–)是循环K-1次,目的是让p结点和q结点之间相隔K-1(为什么是K-1,因为最后是要让p结点指向倒数第1个结点也就是p->next=NULL,我们要找的是倒数第K个结点,中间间隔也就是K-1而不是K)
(3)while(p->next!=NULL)是不断循环,p和q同时向前跑,直到p->next=NULL,此时我们的目的达到了,此时的q,就是我们要的结点。返回q结点的data值就可以啦。
3 通过的代码
#include<iostream>
using namespace std;
struct ListNode{
int data;
ListNode*next;
};
void CreateList(ListNode *pHead)
{
ListNode*head=pHead;
for(int i=2;i<=7;i++)
{
ListNode *newHead=new ListNode;
newHead->data=i;
newHead->next=NULL;
head->next=newHead;
head=newHead;
}
}
int getData(ListNode *pHead,int n)
{
ListNode *p=pHead;
ListNode *q=pHead;
n--;
while(n--)
{
p=p->next;
}
while(p->next!=NULL)
{
p=p->next;
q=q->next;
}
int data=q->data;
return data;
}
int main()
{
int n;
ListNode *node=new ListNode;
node->data=1;
node->next=NULL;
CreateList(node);
cin>>n;
cout<<getData(node,n)<<endl;
return 0;
}
四、写在后面
坚持每天刷一道以上的剑指题目,加油!!为以后的面试做准备!!这一次做的链表题收获了很多,以前没有认真做过链表题,上次面某大厂的实习生也是认识到了这些算法题尤其是链表题的重要性,加油,刷题刷题!!(做的题目都来自牛客网的剑指部分题目)