反转链表
问题描述:
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表节点定义:
struct ListNode
{
int m_nKey;
ListNode* m_pNext ;
}
思路一:可以遍历一遍链表,用一个栈保存链表的结点的数值,然后再遍历链表,同时设置各个结点的值。
代码如下:
#include<stack>
ListNode* ReverseList(ListNode* pHead)
{
stack<int> st ;
ListNode* p = pHead ;
while(p)
{
st.push(p->m_nKey);
p = p->m_pNext ;
}
p = pHead ;
while(p)
{
p->m_nKey = st.top();
st.pop();
p= p->m_pNext
}
return pHead ;
}
这种利用stack实现反转链表的方法,借助了O(n)的空间,没有涉及过多的指针操作,时间复杂度也为O(1)。
思路二:利用双指针的方法,一个指针指向前面反转好的链表,另一个指针指向未反转的链表。
ListNode* ReverseList(ListNode* pHead)
{
ListNode* pReverseHead = NULL ;
ListNode* pNode = pHead ;
ListNode* pPrev = NULL ;
while(pNode)
{
ListNode* pNext = pNode ->m_pNext ;
if(NULL == pNext)
pReverseHead = pNode ;
pNode ->m_pNext = pPrev ;
pPrev = pNode ;
pNode = next ;
}
return pReverseHead ;
}
这种双指针的方法,有点像我们手工反转链表的操作,涉及到一些指针操作,只需要遍历一遍链表即可,时间复杂度为O(N);空间复杂度为O(1)。