力扣单链表例题分析

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

总结

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

相关推荐
计算机小白一个6 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^6 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
大数据追光猿8 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!8 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉8 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生8 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴9 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing9 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财9 小时前
加油站(力扣134)
算法·leetcode·职场和发展
王老师青少年编程9 小时前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛