1.移除链表元素
题解示意图
解题思路:这种类型题我们会很自然的想到创建新链表,然后把原来的链表进行拷贝到新的链表中去,遇见与查找元素相同的就进行跳出,继续去后面进行寻找。
cpp
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
ListNode *newhead,*newTail;
newhead=newTail=NULL;
ListNode*pcur=head;
//判断pcur是否为空,不为空继续后移
while(pcur)
{
if(pcur->val!=val)
{
//判断链表是否为空,若为空头节点等于尾节点
if(newhead==NULL)
{
newhead=newTail=pcur;
}
else
{
newTail->next=pcur;
newTail=newTail->next;
}
}
pcur=pcur->next;
}
if(newhead)//新链表不为空的情况
//一定要是最后一个尾节点为空避免出现最后最后一个元素是要删除的导致无法删除的情况
newTail->next=NULL;
return newhead;
}
2.反转链表
解析:这种的其实较为简单只需要改变指针的指向就可以了
题解示意图
改变指针后的示意图
cpp
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
//判断链表是否为空
if(head==NULL)
{
return head;
}
ListNode * n1,* n2,* n3;
n1=NULL,n2=head,n3=n2->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
{
n3=n3->next;
}
}
return n1;
}
3.合并两个有序列表
这个题其实思路和上面一样,但是为了避免冗余的代码于是就直接开辟了一个新的节点,最后一定不要忘记要释放所开辟的空间,并置为空
题解示意图
cpp
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
// 当一个为空时
if (list1 == NULL) {
return list2;
}
if (list2 == NULL) {
return list1;
}
ListNode *newhead, *newtail;
newhead = newtail = (ListNode*)malloc(sizeof(ListNode));
// 将数据插入到新的链表中
while (list1 && list2) {
if (list1->val < list2->val) {
newtail->next = list1 ;
newtail = newtail->next;
list1 = list1 ->next;
}
else
{ newtail->next = list2;
newtail = newtail->next;
list2 = list2->next;
}
}
// 此时list1或者list2有一个为空那就是其余直接返回另一个
if (list1) {
newtail->next = list1;
}
if (list2) {
newtail->next = list2;
}
// 释放动态开辟的空间
ListNode* node = newhead->next;
free(newhead);
newhead = NULL;
return node;
}
4.链表的回文结构
回文数就是正着读和逆序读都是一样的,因为是链表所以无法从尾部进行倒序读但是可以,通过快慢指针进行找到中间位置,然后利用我们所学的知识对中间靠后的链表进行反转。然后比较值只要不相同直接返回false。
cpp
typedef struct ListNode ListNode;
class PalindromeList {
public:
ListNode *findMid(ListNode *phead)
{
ListNode *fast,*slow;
fast=slow=phead;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
ListNode *reverse(ListNode *phead)
{
ListNode *n1,*n2,*n3;
n1=NULL;
n2=phead;
n3=phead->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
n3=n3->next;
}
return n1;
}
bool chkPalindrome(ListNode* A) {
ListNode *mid=findMid(A);
ListNode *right=reverse(mid);
ListNode *left=A;
while(right)
{
if(right->val!=left->val)
return false;
left=left->next;
right=right->next;
}
//
return true;
}
};
总结
以上是所学的快慢指针,链表反转,这几种方法的掌握对我们后续知识的学习也是很有帮助的。后面我还会对快慢指针进行深一步的探索,期待大家的指正。