面试题18:删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
思路1:递归版
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==nullptr||pHead->next==nullptr)//节点数为0和1时,返回
return pHead;
if(pHead->val == pHead->next->val) //只分两种,当前节点和下一个节点重复,不重复
{
while(pHead!=nullptr&&pHead->next!=nullptr&&pHead->val==pHead->next->val)
{
pHead = pHead->next;
}//找到当前节点与下一个节点不重复的点,从不重复的点开始递归
return deleteDuplication(pHead->next);
}
else
{
pHead->next = deleteDuplication(pHead->next);
return pHead;
}
}
};
思路2 非递归版
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if( pHead == NULL ) return pHead;
ListNode *pre = NULL; //指向前面最晚访问过的不重复结点
ListNode *p = pHead; //指向当前处理的结点
ListNode *q = NULL; //指向当前处理结点后面结点
while( p != NULL )
{
//当前结点p,(其实是p指向当前结点),与它下一个结点p->next的val相同,说明要删掉有这个val的所有结点
if( p->next != NULL && p->next->val == p->val )
{
q = p->next;
//找到q,它指向最后一个与p val相同的结点,那p 到 q (包含) 都是要删除的
while( q != NULL && q->next != NULL && q->next->val == p->val )
{
q = q->next;
}
//如果p指向链表中第一个元素,p -> ... -> q ->... , 要删除p到q, 将指向链表第一个元素的指针pHead指向q->next。
if( p == pHead )
{
pHead = q->next;
}
else//如果p不指向链表中第一个元素,pre -> p ->...->q ->... ,要删除p到q,即pre->next = q->next
{
pre->next = q->next;
}
//当前处理的p要向链表尾部移动
p = q->next;
}
else
{
pre = p;
p = p->next;
}
}
return pHead;
}
};
面试题22:输入一个链表,输出该链表中倒数第k个结点。
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
//头指针为空,输入参数为空时返回空
if(pListHead==NULL||k==0)
return NULL;
ListNode*pTail=pListHead,*pHead=pListHead;
//先让第一个指针向前走k-1步到达第k个节点
for(int i=1;i<k;++i)
{
if(pHead->next!=NULL)
pHead=pHead->next;
else
return NULL;//节点总数小于k
}
//第二个指针也从链表的头指针开始,
//第一个指针到达尾节点时,第二个到达倒数第k个
while(pHead->next!=NULL)
{
pHead=pHead->next;
pTail=pTail->next;
}
return pTail;
}
};
面试题6 从尾到头打印链表
面试题24 反转链表
输入一个链表,从尾到头打印链表每个节点的值。
思路1:
把节点的值从头节点开始放到vector里
反转vector。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> v;
ListNode *p =head;
while (p != nullptr) {
v.push_back(p->val);
p = p->next;
}
reverse(v.begin(),v.end());
return v;
}
};
思路2
把链表反转,在从反转后的链表的头结点遍历
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> v;
ListNode *p =head; //当前节点
ListNode *pre = nullptr; //前一个节点
//反转链表
while(p!=nullptr)
{
ListNode *pnext = p->next; //把后一个节点存起来防止断链
p->next = pre;
pre = p;
p = pnext;
}
//这时的pre 是反转链表的头节点
while(pre!=nullptr)
{
v.push_back(pre->val);
pre = pre->next;
}
return v;
}
};
面试题25 合并两个排序的链表
思路:递归版
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1==nullptr)return pHead2;//递归的边界
if(pHead2==nullptr)return pHead1;
if(pHead1->val < pHead2->val)
{
pHead1->next =Merge(pHead1->next, pHead2);
return pHead1;//返回头指针
}
else
{
pHead2->next =Merge(pHead1, pHead2->next);
return pHead2;//返回头指针
}
}
};
思路2:非递归版
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1==nullptr)return pHead2;
if(pHead2==nullptr)return pHead1;
ListNode *mergeHead=nullptr;
if(pHead1->val < pHead2->val)
{
mergeHead = pHead1; //头指针先赋给值小的
pHead1 = pHead1->next;
}
else
{
mergeHead = pHead2;
pHead2 = pHead2->next;
}
ListNode *p = mergeHead; //头指针先留着要返回,p是工作指针
while(pHead1&&pHead2) //有一个链表到结尾时,结束
{
if(pHead1->val < pHead2->val)
{
p->next = pHead1;
p = p->next;
pHead1 = pHead1->next;
}
else
{
p ->next = pHead2;
p = p->next;
pHead2 = pHead2->next;
}
}
if(pHead1==nullptr)p->next = pHead2;//链表1遍历完了
if(pHead2==nullptr)p->next = pHead1;
return mergeHead;
}
};
面试题52: 两个链表的第一个公共节点
计算两连表的长度差
如果链表1的长度大于链表2的长度
先遍历链表1,遍历的长度就是两链表的长度差
如果链表2的长度大于链表1的长度
先遍历链表2,遍历的长度就是两链表的长度差
开始齐头并进,直到找到第一个公共结点
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2)
{
ListNode* cur1 = pHead1;
ListNode* cur2 = pHead2;
int len1 = getList_len(cur1);
int len2 = getList_len(cur2);
if(len1>len2)
{
int len = len1-len2;
while(len--)
cur1 = cur1->next;
}
else
{
int len = len2-len1;
while(len--)
cur2 = cur2->next;
}
while(cur1!=cur2)
{
cur1=cur1->next;
cur2=cur2->next;
}
return cur1;
}