例1
题号:剑指offer 06, 难度:简单
题目描述:
解题思路:
我用了个栈改变顺序。利用栈先进后出的特性,把元素逐个压进去,再弹出来顺序就反了。
具体代码:
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> nodes;
vector<int> res;
ListNode * pNode = head;
while(pNode != NULL)
{
nodes.push(pNode->val);
pNode = pNode->next;
}
while(!nodes.empty())
{
res.push_back(nodes.top());
nodes.pop();
}
return res;
}
};
例2
题号:剑指offer 24, 难度:简单
题目描述:
解题思路:
假设共有五个节点,1->2->3->4->5,1<-2<-3 4->5,刚翻转完3,可以看到链表是断开的,所以翻转3的时候要保存3->next,用pNext保存。
那翻转链表就可以抽象为两步:
1、保存下一个节点
2、当前节点指向前一个节点。
具体代码:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode * pReversedHead = NULL;
ListNode * pNode = head;
ListNode * pPre = NULL;
while(pNode != NULL)
{
ListNode *pNext = pNode->next;
if (pNext == NULL)
pReversedHead = pNode;
pNode->next = pPre;
pPre = pNode;
pNode = pNext;
}
return pReversedHead;
}
};
例3
题号:剑指offer 35, 难度:中等
思路分三步,每个节点后面克隆一个节点,然后把克隆节点的复杂节点弄好,最后拆分长链表。
/*
// 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) {
Node * node = head;
//克隆一份
while(node != NULL) //原链表每个节点后面都插入一个新节点,新节点的值和原链表一样
{
Node * clone = new Node(node->val);
clone->next = node->next;
node->next = clone;
node = clone->next;
}
//建立random指针
node = head;
while(node != NULL)
{ //从头遍历一遍,如果原链表的节点存在random指针,那这个random指针指向位置的后一个节点,就是新链表的random指针指向的位置。
Node * clone = node->next;
if(node->random != NULL)
{
clone->random = node->random->next;
}
node = clone->next;
}
//拆分
node = head;
Node *cloneHead = NULL;
Node *cloneNode = NULL;
if(node != NULL) //设置好要拆分的两个链表的头
{
cloneHead = cloneNode = node->next;
node->next = cloneNode->next;
node = node->next;
}
while(node != NULL) //把对应的节点放到链表头后面
{
cloneNode->next = node->next;
cloneNode = cloneNode->next;
node->next = cloneNode->next;
node = node->next;
}
return cloneHead;
}
};