链表oj题2(Leetcode)(牛客)——合并两个有序链表;判断回文链表;链表分割

链表oj题2(Leetcode)(牛客)

一,合并两个有序链表

合并两个有序链表(力扣)

1.1分析

这里合并两个链表,我们首先想到的思路就是构建一个新的链表,然后比较两个链表的val值的大小依次插入新链表,这里我们还需要注意几个细节

  1. 如果其中一个链表是空的那那么我们直接返回另外一个非空的链表
  2. 我们在比较插入的时候用的是while循环条件就是两个链表都不为空,那么如果一个链表已经结束了,那么我们再后面应该再把另外一条链表插入完。
    还有一些细节我在我的代码注释中有做标注。

2.2代码

c 复制代码
truct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    //先判断两个链表是否有空链表存在
    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
        return list1;
    }
    struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
    //开始进行插入组成新的链表
    while(list1&&list2)
    {
        if(list1->val<list2->val)
        {
            if(tail==NULL)
            {
                //第一次插入要分开处理
                head=tail=list1;
            }
            else
            {
                tail->next=list1;
                tail=tail->next;
            }
            list1=list1->next;
        }
        else
        {
            if(tail==NULL)
            {
                head=tail=list2;
            }
            else
            {
                tail->next=list2;
                tail=tail->next;
            }
            list2=list2->next;            
        }
    }
    //如果一个链表结束了那么另一个链表要继续插入
    if(list1)
    {
        tail->next=list1;
    }
    if(list2)
    {
        tail->next=list2;
    }
    return head;
}

二,链表的回文结构

判断回文链表(力扣)

2.1分析

我们可以线取到中间的节点,然后把中间之后的链表反转,之后,把前面链表和后面的链表进行比较,即可得出。

注意我们这里需要两个函数:

  1. 找到中间节点
  2. 反转链表
    这个两个函数我的上一篇文章都有提到链表oj1

2.2代码

c 复制代码
struct ListNode*reverseList(struct ListNode* head)
{
    struct ListNode*cur=head;
    struct ListNode*newhead=NULL;
    while(cur)
    {
        struct ListNode*next=cur->next;
        cur->next=newhead;
        newhead=cur;
        cur=next;
    }
    return newhead;
}

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode*slow=head;
    struct ListNode*fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}
bool isPalindrome(struct ListNode* head){
    //先找到中间节点,然后把后面的链表反转依次和前面的比较。
    struct ListNode*mid=middleNode(head);
    struct ListNode*rmid=reverseList(mid);
    while(rmid&&head)
    {
        if(rmid->val!=head->val)
        {
            return false;
        }
        rmid=rmid->next;
        head=head->next;
    }
    return true;
}

三,链表分割

链表分割(牛客)

3.1分析

由于这个题目没有给我们具体的例子我们就自己找一个来观察。

我们假设3为分割数,我们的思路就是分成两个链表最后在链接在一起。分析链表就变成了以下两个链表。

同样的我们要注意特殊情况,如果上面的那个链表是空的呢?这种情况下我们就不能进行链接。所以我们在这里给这两个链表创建一个哨兵位,这样即使链表为空也可以正常的进行链接。有哨兵位还有一个优点就是当我们在进行插入的时候不用再特殊考虑链表为空的第一次插入。

这个图就是我们的思路的整合,这里还要注意一下,我们在最后要把哨兵位都去掉。

3.2代码

c 复制代码
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        //创建哨兵位
        ListNode*lhead;
        ListNode*ltail;
        ListNode*ghead;
        ListNode*gtail;
        lhead=ltail=(ListNode*)malloc(sizeof(ListNode*));
        ghead=gtail=(ListNode*)malloc(sizeof(ListNode*));
        //开始比较
        ListNode*cur=pHead;
        while(cur)
        {
            if(cur->val<x)
            {
                ltail->next=cur;
                ltail=ltail->next;
            }
            else {
            gtail->next=cur;
            gtail=gtail->next;
            }
            cur=cur->next;
        }
        ltail->next=ghead->next;
        gtail->next=NULL;
        ListNode*head=lhead->next;//这一步就是把ihead这个哨兵位去掉
        free(lhead);
        free(ghead);
        return head;
    }
};

四,小结

链表oj题目还有几道题目,每一道题目我们都到细细的钻研,把细节的部分都标上注释,方便以后复习的时候看。

相关推荐
士别三日&&当刮目相看33 分钟前
JAVA学习*String类
java·开发语言·学习
烂蜻蜓40 分钟前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
Mars--1 小时前
网络地址转换技术(2)
网络·智能路由器
Dream Algorithm1 小时前
独立组网和非独立组网
网络
菜鸡中的奋斗鸡→挣扎鸡1 小时前
c++ count方法
开发语言·c++
2301_764602232 小时前
网络体系架构
网络·架构
SunkingYang2 小时前
C++中将记录集的数据复制到Excel工作表中的CRange类CopyFromRecordset函数异常怎么捕获
c++·excel·方法·异常捕获·copyfrom·recordset
1haooo2 小时前
[计算机三级网络技术]第二章:中小型网络系统总体规划与设计方法
网络·经验分享·笔记·计算机网络·智能路由器
cliff,2 小时前
JavaScript基础巩固之小游戏练习
javascript·笔记·学习
武帝为此2 小时前
【计算机网络编码与调制】
服务器·网络·计算机网络