首页 > 其他分享 >单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构

单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构

时间:2024-11-03 19:46:28浏览次数:3  
标签:ListNode OJ 回文结构 next 链表 l1 NULL 节点

目录

 一、合并两个有序链表

 二、链表分割

三、链表的回文结构


u解题的总体思路: 

合并两个有序链表:首先创建新链表的头节点哨兵位:本质上是占位子),为了减少一些判断情况,简化操作。然后我们再创建俩个指针分别指针两个单链表的头然后遍历比较,将两个指针指向节点的最小值接在新链表的后面

链表分割:创建两个新链表lessHead和greatHead一个存储原链表中小于x的节点,一个存储其他的节点,我们按顺序遍历原链表:当循环结束后,我们将存储小于x的节点的新链表lessHead接在另一个新链表greatHead的前面

链表的回文结构:我们利用前面OJ题中的方法,找中间节点(快慢指针),反转链表(三指针法)解这道题,我们找到中间节点后,将中间节点后面的节点的指向反转,然后我们遍历这个反转后的链表与原链表比较,看是否满足条件。

 一、合并两个有序链表

步骤1:

我们新建一个链表,初始化NewHead,NewTail三个指针都指向头节点NewList,然后,我们创建指针l1,l2分别指向list1和list2.

步骤2:当l1和l2指向的节点都不为NULL,循环遍历节点将最小值的节点接在新链表的后面,然后NewTail指向新链表的最后的节点位置上

 

步骤3:

我们将l1和l2指向链表节点不为NULL的接在NewTail的next域上,就完成了合并操作。 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    ListNode *l1 = list1,*l2 = list2;      
    ListNode *NewList = (ListNode*)malloc(sizeof(ListNode));    //创建头节点
    ListNode * NewHead, *NewTail; 
    NewHead = NewTail = NewList;    //初始化俩个指针都指向新链表
    //l1 和 l2 当前节点都不为NULL,遍历
    while(l1 && l2){
        if(l1->val < l2->val){
            NewTail->next = l1;
            l1 = l1->next;     //l1往后走
        }else{
            NewTail->next = l2;
            l2 = l2->next;     //l2往后走
        }
        NewTail = NewTail->next;     //更新NewTail 指向当前新插入的节点
    }
    //两者有一个为NULL(不可能同时为NULL)
    if(l1!=NULL){
        NewTail->next=l1;
    }else{
        NewTail->next=l2;
    }
    return NewList->next;
}

 二、链表分割

 步骤1:

我们首先创建两个新的链表,lessHead存储节点值< x的节点greatHead存储节点值>= x的节点。

步骤2:

我们循环原链表,将每个节点按照判断接在各自的新链表中。

步骤3:

我们将lessHead的lessTail的next域接在greatHead的next前面,这样我们就实现了两个新链表的拼接.(注意:最后要将greatTail的next域置为NULL,防止死循环)

 

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
#include <functional>
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        ListNode *pcur = pHead;
        //创建俩个头节点,分别存储小节点,和大节点
        ListNode *lessHead = (ListNode*)malloc(sizeof(ListNode));
        ListNode *lessTail = lessHead;
        ListNode *greatHead =  (ListNode*)malloc(sizeof(ListNode));
        ListNode *greatTail = greatHead;
        //循环遍历原链表中的每个节点
        while(pcur){
            if(pcur->val < x){
                lessTail->next = pcur;
                lessTail = lessTail->next;     //尾指针后移当新插入的节点 
            }else{
                greatTail->next = pcur;
                greatTail = greatTail->next;    //尾节点后移到新插入的节点
            }
            pcur = pcur->next;
        }
        //拼接两个新链表,将lessHead接入到greatHead后面
        lessTail->next = greatHead->next;
        greatTail->next = NULL;     //将最后的节点next域置为NULL
        return lessHead->next;
    }
};

三、链表的回文结构

 步骤1:

我们首先写出找中间节点的函数middleNode,和反转链表的函数reverseList找到中间节点,然后,将中间节点后面的链表反转。(这两个函数在上个文章中详细讲解过,这里不再重点讲述

 步骤2:

反转以mid为头节点的链表。 

从这里可以看出我们的链表变成了俩个部分,然后我们遍历这两个链表比较各自节点的值是否相等相等说明我们原链表就是回文链表

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
    //反转链表
    ListNode* reverseList(ListNode* head){
        ListNode*n1,*n2,*n3;
        n1 = NULL;
        n2 = head;
        if(n2==NULL){
            return NULL;
        }
        n3 = n2->next;
        while(n2){
            n2->next = n1;
            n1 = n2;
            n2 = n3;
            if(n3)
                n3 = n3->next;
        }
        return n1;
    }
    //找中间节点
    ListNode* middleNode(ListNode* head){
        if(head==NULL){
            return NULL;
        }
        ListNode *slow,*fast;
        slow = fast = head;
        while(fast && fast->next){
            slow = slow->next;    //slow走一步
            fast = fast->next->next;    //fast走两步
        }
        return slow;
    }
    bool chkPalindrome(ListNode* A) {
        ListNode*phead = A;
        ListNode*mid = middleNode(A);    //找中间节点
        ListNode*pcur = reverseList(mid);   //反转以中间节点为头的后面的节点
        while(pcur){
            if(pcur->val != phead->val){
                return false;
            }
            pcur = pcur->next;
            phead = phead->next;
        }
        //循环正常结束,返回true
        return true;
    }
};

标签:ListNode,OJ,回文结构,next,链表,l1,NULL,节点
From: https://blog.csdn.net/2301_80966914/article/details/143452688

相关文章

  • LeetCode 19. 删除链表的倒数第 N 个结点(java)
    目录题目描述:代码:第一种:第二种:题目描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]示例3:输入:head=[1,2],n=1输出:[1]代码:第一种:......
  • 【STL_list 模拟】——打造属于自己的高效链表容器
    一、list节点​list是一个双向循环带头的链表,所以链表节点结构如下: template<classT> structListNode { Tval; ListNode*next; ListNode*prve; ListNode(intx) { val=x; next=prve=this; } };二、list迭代器2.1、list迭代器与vector......
  • 【C语言学习】7步轻松掌握C语言链式结构,你也能成为高手!与数组说拜拜,链表你好
    ......
  • 东华大学oj航班时间
    大家来搜到我这篇博客可能是出于两个目的,一种是真的没有思路,另一种呢是不知道该怎么输入。注:本题我只用到函数而且用法简单。航班时间时间限制:1s类别:循环结构->较难问题描述【问题背景】小h前往美国参加了蓝桥杯国际赛。小h的女朋友发现小h上午十点出发,上午十二点......
  • CF1658E Gojou and Matrix Game
    题意题解设f[i,j]表示(i,j)先手必胜/必败则全局max一定必败,因为先手走出去后手走回来,重复无限次后必输然后全局max外(距离>k)的必胜,因为可以走到全局max之后可以发现,下一个必败的是全局max范围内的次max,因为次max不能①走出全局max范围②走到全局max③走到一个比自己小的数(......
  • 单双链表(数组模拟)笔记
    单双链表(数组模拟)笔记如题,我们要使用数组来模拟链表这个数据结构区别于传统的结构体链表(动态链表):structnode{ intvalue; structnode*next;//指向下一个节点的指针}user_define_name;//调用链表的别称数组模拟链表(静态链表)的速度更快,但是对于空间的优化不如动态链表......
  • LeetCode24:两两交换链表中的节点
    原题地址:.-力扣(LeetCode)题目描述给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1]......
  • LeetCode25:K个一组翻转链表
    原题地址:.-力扣(LeetCode)题目描述给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需......
  • POJ1511-Invitation Cards
    继续刷邝斌飞最短路专题POJ(TimeLimit:8000MS、MemoryLimit:262144K)洛谷(3s、0B) —— 买一送一洛谷(时间限制:559ms、内存限制:1.46GB)最爱的可用平台(总时间限制: 3000ms 内存限制: 65536kB)HDU(TimeLimit:5000MS、MemoryLimit:65536K)......
  • 代码随想录一刷day6 (链表day2)(链表完结)
    24.两两交换链表中的节点分三步走;1.创建dummyhead2.三个指针 cur  t1 t23.  cur->next=t2;  t1->next=t2->next;  t2->t1->next; 最后让cur=t1;注意最后返回的是dummyhead-》next 而不是head;注意最后deletedummyhead19.删除链表的倒数第N个节点注......