力扣单链表例题分析

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

总结

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

相关推荐
闻缺陷则喜何志丹5 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin24 分钟前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿39 分钟前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd39 分钟前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo61743 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神2 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
云边有个稻草人2 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
半盏茶香2 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法