剑指offer06-从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
思路:
使用栈做中间存储介质,先把链表顺序存储到栈里,此时实现倒序,然后再从栈里取出到vector内。
注意:
1.vector本身是动态数组,直接创建即可,不需要使用new;
2.vector插入元素使用push_back()函数。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int>list;
vector<int> zu;
ListNode *p;
p=head;
while(p!=NULL){
list.push(p->val);
p=p->next;
}
while(!list.empty())
{
zu.push_back(list.top());
list.pop();
}
return zu;
}
};
/*
执行用时:4ms
内存消耗:8.4MB
*/
剑指offer24-反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
思路
此题思路参考了leetcode社区的大佬们的做法。
做法有很多,我选择了递归算法。
核心算法就是,每次反转时,把第一个元素替换成最后一个元素,本来是head的next指针指向剩下的链表,现在换成它的下一个元素指向它(此时它后面的链表一定是反转完的)。
所以要先递归返回,然后再替换next指针关系。
注意:
虽然每次递归感觉都新建了一个链表,但实际上进行操作的是同一条链表,同一批结点(没有新建结点),我个人的理解是新建了链表指针。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) //递归
{
if(head==NULL||head->next==NULL)//递归的终点是链表开始就为空或者链表只有一个元素
{
return head;
}
//当链表不为空时,当前第一个节点是反转链表的最后一个节点
ListNode* reversehead=reverseList(head->next);//新建反转链表(除最后一个节点之后的后面的链表)
head->next->next=head;//给反转链表插入最后一个节点
head->next=NULL;
return reversehead;
}
};
/*
执行时间:4ms
内存消耗:8.3MB
*/
误区
开始有些被上一道题误导到,一门心思想再用一个栈做介质,然后完全新建一条链表,新建一堆节点。然后我就卡在了创建节点这一步,先不说能不能建好,建好后我也得runtime error(用递归的时候一开始我多建了一个指针就导致runtime error了)。
剑指offer35-复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例
思路
依旧是在评论区和解题区跌跌撞撞寻找解答
首先这个题目的难点在于他是个复杂链表的复制,如果没有随机指针,他可以直接一个一个地直接复制。
但是由于随机指针指向不确定,有可能会指向还没创建的节点,所以复杂。
我用的是原地修改法。首先只创建同元素的节点,分别插入每个被复制节点之后,random都默认为空。
然后依次修改random指针,参照前面的节点,指向其对应节点的后一个节点(只针对指向非空节点的指针)。
最后再依次修改每个节点的next指针,使他们变成两条链。
难点
对我来说,了解思路和算法并不难,难点在于创建节点和指针,哪些地方需要带星花,哪里需要加new;还有就是while判断语句容易出错。还需要多练习。
代码
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL)
return NULL;//如果为空,输出null
//不为空的话开始复制
Node *p=head;
while(p!=NULL){
Node* newnode=new Node(p->val);//新建节点同元素
newnode->next=p->next;//插入被复制节点之后
p->next=newnode;
p=p->next->next;
}
p=head;
while(p!=NULL){
if(p->random!=NULL){
p->next->random=p->random->next;
}
p=p->next->next;
}
p=head;
Node* copyhead=head->next;
Node* q=copyhead;
while(p!=NULL){
p->next=p->next->next;
p=p->next;
if(q->next!=NULL){
q->next=q->next->next;
q=q->next;
}
}
return copyhead;
}
};
/*
执行用时:4ms
内存消耗:11MB
*/