转载请注明作者和出处: http://blog.csdn.net/john_bh/
github地址:https://github.com/johnbhlm/SwordFingerOffer
文章目录
完整代码,已经同步到github:https://github.com/johnbhlm/SwordFingerOffer,欢迎关注,欢迎star~
1. 题目
输入一个链表的头结点,从尾到头反过来打印出每个节点的值。
链表节点定义如下:
struct ListNode{
int m_nKey;
ListNode* m_pNext;
};
2. 解题思路
2.1 思路1 — 栈(先进后出的原则)
通常,这种情况下,不希望修改原链表的结构
。返回一个反序的链表,这就是经典的“后进先出”,可以使用栈实现这种顺序。每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,给一个新的链表结构,这样链表就实现了反转。
2.2 思路2 — 库函数
用库函数,每次扫描一个节点,将该结点数据存入vector中,如果该节点有下一节点,将下一节点数据直接插入vector最前面,直至遍历完,或者直接加在最后,最后调用reverse。
2.3 思路3 — 递归
递归在本质上就是一个栈结构,于是很自然地想到用递归来实现。要实现反过来输出链表,每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结构就反过来了。
算法流程如下:
- 只要当前节点不为NULL,也就是链表没到头,就一直递归
- 在递归结束时,将元素压入
这样当递归结束进行返回时,会将递归栈中的数据依次压入vector中,而压入的顺序就是栈中的顺序,即从尾到头
3. python 实现
# -*- coding:utf-8 -*-
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
# 解法1:栈
def printListFromTailToHead(listNode):
# write code here
stack = []
result = []
node_p = listNode
while node_p:
stack.append(node_p.val)
node_p = node_p.next
while stack:
result.append(stack.pop(-1))
return result
# 解法2:递归
result = []
def printListFromTailToHead(listNode):
# write code here
if listNode:
printListFromTailToHead(listNode.next)
result.append(listNode.val)
return result
# 解法3:头插
class Solution:
def printListFromTailToHead(self, listNode):
# write code here
result = []
head = listNode
while head:
result.insert(0,head.val)
head =head.next
return result
# 解法4:利用list 特性
class Solution:
def printListFromTailToHead(self, listNode):
# write code here
if not listNode:
return []
result = []
while listNode.next is not None:
result.extend([listNode.val])
listNode = listNode.next
result.extend([listNode.val])
return result[::-1]
4. C++ 实现
4.1 思路1 — 栈
struct ListNode {
int val;
struct ListNode *next;
};
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
stack<int> stk;
ListNode *pHead = head;
while (pHead != NULL) {
stk.push(pHead->val);
pHead = pHead->next;
}
while (!stk.empty()) {
result.push_back(stk.top());
stk.pop();
}
return result;
}
};
4.2 思路2 — 库函数
struct ListNode {
int val;
struct ListNode *next;
};
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
if (head != NULL) {
result.insert(result.begin(), head->val);
while (head->next != NULL) {
result.insert(result.begin(), head->next->val);
head = head->next;
}
}
return result;
}
};
自定义 vector 方法:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
ListNode *pHead = head;
int length = 0;
while(pHead != NULL) {
length++;
pHead = pHead->next;
}
vector<int> result(length,0);
while (head != NULL) {
result[--length] = head->val;
head = head->next;
}
return result;
}
};
4.3 思路3 — 递归
class Solution{
public:
vector<int> printListFromTailToHead(struct ListNode* head){
vector<int> result;
printListFromTailToHeadRecursion(head, result);
return result;
}
void printListFromTailToHeadRecursion(struct ListNode* head, vector<int> &result){
if (head != NULL){
printListFromTailToHeadRecursion(head->next, result);
result.push_back(head->val);
}
}
};
上面用辅助函数的方法,每次都需要传递一个vector,很麻烦啊,我们可以直接用一个成员变量来存储:
class Solution {
public:
vector<int> result;
vector<int> printListFromTailToHead(ListNode* head) {
if (head == NULL) {
return result;
}
result = printListFromTailToHead(head->next);
result.push_back(head->val);
return result;
}
};
4.4 官方代码
/*
* Question Description:
* (Question 44 in <Coding Intervies>) Given a sorted linked list, please delete all duplicated numbers and
* leave only distinct numbers from the original list.
*/
#include <stdio.h>
#include "../Utilities/list.h"
void deleteDuplication(ListNode** pHead)
{
if(pHead == NULL || *pHead == NULL)
return;
ListNode* pPreNode = NULL;
ListNode* pNode = *pHead;
while(pNode != NULL)
{
ListNode *pNext = pNode->m_pNext;
bool needDelete = false;
if(pNext != NULL && pNext->m_nValue == pNode->m_nValue)
needDelete = true;
if(!needDelete)
{
pPreNode = pNode;
pNode = pNode->m_pNext;
}
else
{
int value = pNode->m_nValue;
ListNode* pToBeDel = pNode;
while(pToBeDel != NULL && pToBeDel->m_nValue == value)
{
pNext = pToBeDel->m_pNext;
delete pToBeDel;
pToBeDel = NULL;
pToBeDel = pNext;
}
if(pPreNode == NULL)
*pHead = pNext;
else
pPreNode->m_pNext = pNext;
pNode = pNext;
}
}
}
// ==================== Test Code ====================
void Test(char* testName, ListNode** pHead, int* expectedValues, int expectedLength)
{
if(testName != NULL)
printf("%s begins: ", testName);
deleteDuplication(pHead);
int index = 0;
ListNode* pNode = *pHead;
while(pNode != NULL && index < expectedLength)
{
if(pNode->m_nValue != expectedValues[index])
break;
pNode = pNode->m_pNext;
index++;
}
if(pNode == NULL && index == expectedLength)
printf("Passed.\n");
else
printf("FAILED.\n");
}
// some nodes are duplicated
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(4);
ListNode* pNode6 = CreateListNode(4);
ListNode* pNode7 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = {1, 2, 5};
Test("Test1", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// all nodes are unique
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ListNode* pNode6 = CreateListNode(6);
ListNode* pNode7 = CreateListNode(7);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = {1, 2, 3, 4, 5, 6, 7};
Test("Test2", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// all nodes are duplicated except one
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(1);
ListNode* pNode4 = CreateListNode(1);
ListNode* pNode5 = CreateListNode(1);
ListNode* pNode6 = CreateListNode(1);
ListNode* pNode7 = CreateListNode(2);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = {2};
Test("Test3", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// all nodes are duplicated
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(1);
ListNode* pNode4 = CreateListNode(1);
ListNode* pNode5 = CreateListNode(1);
ListNode* pNode6 = CreateListNode(1);
ListNode* pNode7 = CreateListNode(1);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
Test("Test4", &pHead, NULL, 0);
DestroyList(pHead);
}
// all nodes are duplicated in pairs
void Test5()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(2);
ListNode* pNode5 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(3);
ListNode* pNode7 = CreateListNode(4);
ListNode* pNode8 = CreateListNode(4);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ListNode* pHead = pNode1;
Test("Test5", &pHead, NULL, 0);
DestroyList(pHead);
}
// nodes are duplicated in pairs except two
void Test6()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(4);
ListNode* pNode7 = CreateListNode(5);
ListNode* pNode8 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ListNode* pHead = pNode1;
int expectedValues[] = {2, 4};
Test("Test6", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// a list with two unique nodes
void Test7()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ConnectListNodes(pNode1, pNode2);
ListNode* pHead = pNode1;
int expectedValues[] = {1, 2};
Test("Test7", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// only one node in a list
void Test8()
{
ListNode* pNode1 = CreateListNode(1);
ConnectListNodes(pNode1, NULL);
ListNode* pHead = pNode1;
int expectedValues[] = {1};
Test("Test8", &pHead, expectedValues, sizeof(expectedValues)/sizeof(int));
DestroyList(pHead);
}
// a list with only two duplidated nodes
void Test9()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ConnectListNodes(pNode1, pNode2);
ListNode* pHead = pNode1;
Test("Test9", &pHead, NULL, 0);
DestroyList(pHead);
}
// empty list
void Test10()
{
ListNode* pHead = NULL;
Test("Test10", &pHead, NULL, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
Test10();
return 0;
}
参考链接: