专题一介绍了链表以及链表的一些简单的操作,这章专题探究剑指offer里的一些面试题目。
(1)面试题16 P112
输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
法一:递归
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL)
return pHead;
ListNode* pReverse=ReverseList(pHead->next);
pHead->next->next=pHead;
pHead->next=NULL;
return pReverse;
法二:网上看到别人的解法,也是用两个指针记录当前点的前驱和后驱,不过比答案的代码简洁一些
ListNode* ReverseList(ListNode* pHead)
{
ListNode* pre = NULL;
ListNode* next = NULL;
while (pHead != NULL)
{
next = pHead->m_pNext;//记录后驱结点
pHead->m_pNext = pre;// 把指针从指向后一个结点改为指向前一个
pre = pHead; //记录前驱结点
pHead = next; //向后一个结点
}
return pre;
}
(2)输入一个链表,输出该链表倒数第k个结点
方法一:看到这个题我本能的想到了堆栈,但是这样要遍历两次,不是很高效,还要额外的空间
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
std::stack<ListNode*> nodes;
if(pListHead == NULL || k ==0)//不要忘记k=0的情况
return NULL;
ListNode* pNode = pListHead;
int count = 0;
while (pNode != NULL)
{
nodes.push(pNode);
count ++;
pNode = pNode->next;
}
if (k>count) //如果k比链表长度大
return NULL;
else
{
for(int i = 1;i<k;i++)
nodes.pop();
return nodes.top();
}
}
};
方法二就是按照书中给的答案,设立两个指针去移动
(3)输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
思路:这也是典型的可以用递归解决的问题
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL)
return pHead2;
if (pHead2 == NULL)
return pHead1;
ListNode* pMergeHead = NULL;
if (pHead1->m_Value < pHead2->m_Value)
{
pMergeHead = pHead1;
pMergeHead->m_pNext = Merge(pHead1->m_pNext,pHead2);
}
else
{
pMergeHead = pHead2;
pMergeHead->m_pNext = Merge(pHead1,pHead2->m_pNext);
}
return pMergeHead;
}