题目1 反转链表
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
解1 迭代法
设置三个指针p1,p2,p3,初始分别指向前三个元素
p2指向p1,并向后移动三个指针,直到p3指向NULL
并将最后一个元素指p1.
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//链表为NULL,或只有一个元素
if(head == NULL || head->next == NULL)
return head;
//定义并初始化三个指针
ListNode* p1 = head;
ListNode* p2 = head->next;
ListNode* p3 = head->next->next;
//head指向NULL
head->next = NULL;
//往后遍历,并赋值反转
while(p3)
{
p2->next = p1;
p1 = p2;
p2 = p3;
p3 = p3->next;
}
//对于最后一个元素单独处理
p2->next = p1;
//返回链表头
return p2;
}
};
解1 递归法
每次给函数传入两个指针p1,p2,初始分别指向前两元素,开始往后递归遍历。
当遍历到结尾,开始返回并p2指向p1,进行反转。
class Solution {
public:
//额外设置指针,标记递归到最后时,反转后的起始节点(即最后一个结点)
ListNode* pHead = NULL;
ListNode* reverseList(ListNode* head)
{
//链表为NULL,或只有一个元素
if(head == NULL || head->next == NULL)
return head;
//递归遍历,初始传入链表前两个元素
Turn(head,head->next);
//头节点指NULL
head->next = NULL;
return pHead;
}
void Turn(ListNode* p1,ListNode* p2)
{
//遍历到结尾,尾结点标记给pHead,并开始返回
if(p2 == NULL)
{
pHead = p1;
return;
}
Turn(p1->next,p2->next);
//p2指向p1
p2->next = p1;
}
};
题目2 二进制链表转整数
遍历链表,每遍历一位,num的值左移一位加上结点值。
class Solution {
public:
int getDecimalValue(ListNode* head) {
int num = 0;
while(head)
{
num = (num<<1)+head->val;
head = head->next;
}
return num;
}
};
题目3 删除链表重复元素
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
解1 快慢指针
- 设置两个指针pQuick、pSlow,初始指向链表前两个元素
- 若pQuick,pSlow指向的数据相同,则只移动pSlow
- 反之,两个指针一起向后移动
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
//链表空
if(head == NULL) return head;
//初始两个指针的值,链表前两个元素
ListNode* pQuick= head;
ListNode* pSlow = head->next;
//循环遍历
while(pSlow)
{
//值相同
if(pQuick->val == pSlow->val
//移动后一个指针
pSlow = pSlow->next;
else
{
//包含重复元素移动过后,再遇到不同元素的情况,因此要执行一步pQuick下一个指向pSlow
pQuick->next = pSlow;
//两个指针后移
pQuick = pSlow;
pSlow = pSlow->next;
}
}
//链表最后有重复元素的情况
pQuick->next = pSlow;
return head;
}
};
解2 递归
- 递归遍历链表
- 返回过程中,返回值拼接到上次递归结点后面
- 若下一节点和上一节点值不同,正常返回本次head即可
- 若相同,则该节点额外赋值给pNode,一直返回该节点,直到遇到不同的结点
class Solution {
public:
ListNode* pNode = NULL;
ListNode* deleteDuplicates(ListNode* head) {
//若为走到最后,继续递归
if(head)
{
pNode = deleteDuplicates(head->next);
}
//如果返回结点的值和head值相同,返回原pNode
if(head && pNode && pNode->val == head->val)
{
return pNode;
}
//head下一个指向pNode
if(head)
head->next = pNode;
//正常返回head即可
return head;
}
};