力扣单链表例题分析

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;
    }
};

总结

以上是所学的快慢指针,链表反转,这几种方法的掌握对我们后续知识的学习也是很有帮助的。后面我还会对快慢指针进行深一步的探索,期待大家的指正。

相关推荐
To_OC8 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎9 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC9 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
delishcomcn10 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹10 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
雪碧聊技术11 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划
延凡科技13 小时前
多场景落地复盘:端边云架构无人机智能巡检系统设计与实践
大数据·数据结构·人工智能·科技·架构·无人机·能源
CV-Climber13 小时前
检索技术的实际应用
人工智能·算法
hhzz14 小时前
Tiger AI Platform平台中增加人脸识别功能
图像处理·人工智能·算法·计算机视觉·大模型