Leetcode---剑指Offer题6---单链表反转 1、介绍 2、题解 3、变形题
剑指Offer-面试题6---从尾到头打印链表
https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
输入一个链表的头结点,按照链表从尾到头的顺序返回一个vector数组。
2、题解
C#
时间O(n),无额外空间开销
public int[] ReversePrint(ListNode head)
{
int len = 0;
ListNode temp = head;
while (temp != null)
{
len++;
temp = temp.next;
}
ListNode temp2 = head;
int[] numArr = new int[len];
for (int i = len-1; i >=0; i--)
{
numArr[i] = temp2.val;
temp2 = temp2.next;
}
return numArr;
}
c++
std::vector<int> printListFromTailToHead(ListNode* head)
{
std::vector<int> vals;
if(head != nullptr)
{
ListNode* temp = head;
while(temp != nullptr){
//直接把值添加到数组开头,相当于翻转了
vals.insert(vals.begin(),temp->val);
temp = temp->next;
}
}
return vals;
}
3、变形题
输入链表头结点,把链表翻转后返回。
本人写法:利用了vector,所以增加了空间开销
ListNode* printListFromTailToHead(ListNode* head)
{
if(head != nullptr){
//先翻转链表
std::vector<ListNode*> nodes;
ListNode* temp = head;
while(temp != nullptr){
nodes.insert(nodes.begin(),temp);
temp = temp->next;
}
//再翻转next指向
for(int i=0;i<nodes.size()-1;i++){
nodes[i]->next = nodes[i+1];
}
nodes[nodes.size()-1]->next = nullptr;
return nodes[0];
}
return head;
}
更好点的写法:定义三个指针分别指向当前结点、前一个结点、后一个结点。然后翻转每一个指向,最后返回第一个结点(刚开始的头结点)。
ListNode* printListFromTailToHead(ListNode* head)
{
//当前节点、前一个结点、后一个结点、翻转后的头结点
ListNode* currentNode = head;
ListNode* frontNode = nullptr;
ListNode* nextNode = nullptr;
ListNode* newHead = nullptr;
while(currentNode != nullptr){
//如果是最后一个结点,赋值后退出
if(currentNode->next == nullptr){
currentNode->next = frontNode;
newHead = currentNode;
break;
}
nextNode = currentNode->next;
//翻转
currentNode->next = frontNode;
frontNode = currentNode;
currentNode = nextNode;
nextNode = currentNode->next;
}
return newHead;
}