1、反转链表
题目:定义一个函数,输入一个链表的头结点,反转改链表并输出反转后链表的头结点。
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
//反转链表
ListNode* ReverseList(ListNode* pHead)
{
/*忽略错误输入应该加一些指针空、只有一个节点的判断*/
ListNode* pReversedHead = NULL; //反转后的头结点
ListNode* pNode = pHead; //当前结点
ListNode* pPrev = NULL; //前一个结点
/*
核心思想就是要保留当前结点的前一个结点,好知道怎么反转;
保留当前结点的下一个结点,避免链表断裂;
*/
while(pNode != NULL)
{
ListNode* pNext = pNode->m_pNext;// 当前结点的后一个结点
if (pNext == NULL)
{
pReversedHead = pNode;
}
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
2、两个链表的第一个公共结点。
题目:输入两个链表,找到它们的第一个公共结点。
有两种方法,方法一:使用辅助栈,分别将链表压栈,然后同时从栈顶弹出,比较,第一个不同的结点即为第一个公共结点;
方法二:不适用辅助栈。代码如下:
//两个链表的第一个公共结点
//获取链表长度
unsigned int GetListLength(ListNode* pHead)
{
unsigned int nLength = 0;
ListNode* pNode = pHead;
while(pNode != NULL)
{
++nLength;
pNode = pNode->m_pNext;
}
return nLength;
}
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
{
//1、获取两个链表长度
unsigned int nLength1 = GetListLength(pHead1);
unsigned int nLength2 = GetListLength(pHead2);
int nLengthDir = nLength1 - nLength2;
/*
核心思想是长的链表先走k步,然后两个链表同时遍历,直到
找到相同的一个结点
*/
ListNode* pListHeadLong = pHead1;
ListNode* pListHeadShort = pHead2;
if (nLength2 > nLength1)
{
pListHeadLong = pHead2;
pListHeadShort = pHead1;
nLengthDir = nLength2 - nLength1;
}
// 先在长链表上走几步,再同时遍历两个链表
for (int i = 0; i < nLengthDir; i++)
{
pListHeadLong = pListHeadLong->m_pNext;
}
while((pListHeadLong != NULL) && (pListHeadShort != NULL) && (pListHeadLong != pListHeadShort))
{
pListHeadLong = pListHeadLong->m_pNext;
pListHeadShort = pListHeadShort->m_pNext;
}
// 得到第一个公共结点
ListNode* pFirstCommonNode = pListHeadLong;
return pFirstCommonNode;
}