C++链表基本用法及LeetCode经典链表题目汇总

链表基本用法:

目录

链表基本用法:

C++链表及基本操作

LeetCode链表经典题目汇总:

2. 两数相加

19. 删除链表的倒数第 N 个结点

21. 合并两个有序链表

23. 合并K个升序链表

24. 两两交换链表中的节点

25. K 个一组翻转链表

61. 旋转链表

92. 反转链表 II

141. 环形链表

142. 环形链表 II

160. 相交链表

328. 奇偶链表


C++链表及基本操作

//创建单链表
/*
1.创建头节点head,并且将当前结点p指向头结点(p=head)
2.创建下一个结点q,当前结点p的下一结点为q(p->next=q)
3.结点p后移一位(p = p->next)
*/
#include <iostream>
#include <vector>
using namespace std;
struct ListNode {
        int val;
        struct ListNode* next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
};
//插入节点
/*
1.判断原链表是否是空链表,如果是,将head指向新增结点
2.如果不是空链表,向链表尾部插入新结点
*/
ListNode* insertNode(ListNode* head, int data) {
        ListNode* newNode = new ListNode(data);
        ListNode* p = head;
        if (p == nullptr) {
                head = newNode;
        }
        else {
                while (p->next != nullptr) {
                        p = p->next;
                }
                p->next = newNode;
        }
        return head;
}

//删除节点
/*
1.空链表直接返回
2.非空链表需要删除的结点不存在
3.非空链表需要删除的结点存在,是头结点和不是头结点两种情况
*/
ListNode* deleteNode(ListNode* head, int data) {
        ListNode* p = head;
        //空链表直接返回
        if (p == nullptr) {
                return head;
        }
        else {
                //判断是否为头结点
                if (p->val == data) {
                        head = p->next;
                        delete p;
                        return head;
                }
                else {
                        //遍历到改结点,删除
                        while (p->next != nullptr && p->next->val != data) {
                                p = p->next;
                        }
                        //遍历完链表却没有要删除的结点
                        if (p->next == nullptr) {
                                return head;
                        }
                        else {
                                ListNode* deleteNode = p->next;
                                p->next = deleteNode->next;
                                delete deleteNode;
                                return head;
                        }
                }
        }
}

//反转链表
/*
假设pNode是当前的节点,pPrev是pNode前面的节点,PNext是PNode后面的节点,那么:
                当pNode不为nullptr,且pNext不为nullptr的时候
1.将pNode指向pPrev(pNode->next = pPrev)
2.将pNode给pPrev(pPrev= pNode)
3.将pNext给pNode(pNode = pNext)
4.当pNode不为nullptr,且pNext==nullptr的时候,把反转后的头部指向pNode
*/
ListNode* reverseNode(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* p = head;
        ListNode* reserveHead = nullptr;
        while (p != nullptr) {
                ListNode* pNext = p->next;
                if (pNext == nullptr) {
                        reserveHead = p;
                }
                p->next = prev;
                prev = p;
                p = pNext;
        }
        return reserveHead;
}

//倒数第K个节点
/*思想:设置快慢指针,快指针比慢指针多走k - 1步,那么快指针走到终点的时候,慢指针指向倒数第K个结点*/
ListNode* FindKthToTail(ListNode* head, unsigned int k) {
        if (head == nullptr || k == 0) {
                return nullptr;
        }
        //快指针
        ListNode* pAhead = head;
        //判断K是不是超出了链表的长度
        for (int i = 0; i < k - 1; i++) {
                if (pAhead->next != nullptr) {
                        pAhead = pAhead->next;
                }
                else {
                        return nullptr;
                }
        }
        //慢指针
        ListNode* pBhead = head;
        while (pAhead->next != nullptr) {
                pAhead = pAhead->next;
                pBhead = pBhead->next;
        }
        return pBhead;
}

//是否有环
//判断链表是否有环,如果有,找出环的入口节点
/*
判断链表是否有环
思想:可以设置快慢指针,快指针一次走两步,慢指针一次走一步,如果快指针追上了走的慢的指针,那么链表有环,如果走到了链表尾部都没有追上,说明链表无环。
注意:快指针与慢指针是否为nullptr的判断
如果有环,返回入口节点
思想:返回的节点一定在环内,如果计算出环中节点的个数count,快指针比慢指针多走count步,那么两个指针相遇时,就是环的入口节点
*/
//判断快慢指针是否相遇
ListNode* meetNode(ListNode* head) {
        ListNode* p = head;
        if (p == nullptr) {
                return nullptr;
        }
        //设置慢指针
        ListNode* slowNode = p->next;
        if (slowNode == nullptr) {
                return nullptr;
        }
        //设置快指针
        ListNode* fastNode = slowNode->next;
        while (fastNode != nullptr && slowNode != nullptr) {
                //相遇
                if (fastNode == slowNode) {
                        return fastNode;
                }
                //slowNode走一步
                slowNode = slowNode->next;
                //fastNode走两步
                fastNode = fastNode->next;
                if (fastNode->next != nullptr) {
                        fastNode = fastNode->next;
                }
        }
        return nullptr;
}
//计算环中节点的个数
int countCycleNode(ListNode* pMeet) {
        int count = 0;
        ListNode* pNode = pMeet;
        while (pNode->next != pMeet) {
                ++count;
                pNode = pNode->next;
        }
        ++count;
        return count;
}

//计算环的入口节点
ListNode* entryNodeFloop(ListNode* phead) {
        ListNode* meet = meetNode(phead);
        if (meet == nullptr) {
                return nullptr;
        }
        int count = countCycleNode(meet);
        ListNode* aheadNode = phead;
        ListNode* behindNode = phead;
        for (int i = 0; i < count; i++) {
                aheadNode = aheadNode->next;
        }
        while (aheadNode != behindNode) {
                aheadNode = aheadNode->next;
                behindNode = behindNode;
        }
        ListNode* entry = aheadNode;
        return entry;
}
int main()
{
        int num;
        cin >> num;
        ListNode* head = new ListNode(num);
        ListNode* p = head;
        尾插法创建单链表
        //while (cin >> num) {
        //        ListNode* q = new ListNode(num);
        //        p->next = q;
        //        p = p->next;
        //}
        insertNode(head, 3);
        insertNode(head, 4);
        insertNode(head, 5);
        
        deleteNode(head, 3);
        ListNode* reverseN = reverseNode(head);
        ListNode* pBhead = FindKthToTail(reverseN, 1);
        cout << "pBhead:" << pBhead->val << endl;
        //遍历链表
        ListNode* m = reverseN;
        while (m != nullptr) {
                cout << m->val << endl;
                m = m->next;
        }
        return 0;
}

LeetCode链表题目汇总:

首先对单链表的定义:

/**

 * Definition for singly-linked list.

 * struct ListNode {

 *     int val;

 *     ListNode *next;

 *     ListNode() : val(0), next(nullptr) {}

 *     ListNode(int x) : val(x), next(nullptr) {}

 *     ListNode(int x, ListNode *next) : val(x), next(next) {}

 * };

 */

2. 两数相加

难度中等

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

 

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

来自 <力扣>

题解:重点考虑最后的进位

#构造新链表赋值

class Solution:

    def addTwoNumbers(selfl1: ListNode, l2: ListNode) -> ListNode:

        flag = 0 #进位

        res = cur = ListNode()

        while l1 or l2:

            x = l1.val if l1 else 0

            y = l2.val if l2 else 0

            total = x + y + flag

            cur.next = ListNode(total%10)

            flag = total // 10

            if l1: l1 = l1.next

            if l2: l2 = l2.next

            cur = cur.next

        if flag: cur.next = ListNode(flag)

        return res.next 

 

 

19. 删除链表的倒数第 N 个结点

难度中等

给你一个链表,删除链表的倒数第 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]

来自 <力扣>

题解:

解法1:

 //快慢指针:时间O(n),空间O(1)

class Solution {

public:

    ListNode* removeNthFromEnd(ListNode* headint n) {

        if(head==nullptr || n==0){

            return nullptr;

        }

        ListNode *dummy = new ListNode(0,head);

        //快慢指针,快指针比慢指针多走n-1步,快指针到链表尾端,慢指针在链表的倒数第n个结点

        ListNode* slow = dummy,*fast=head;

        for(int i=0;i<n-1;i++){

            if(fast->next)

                fast = fast->next;

            else

                return nullptr;

        }

        while(fast->next){

            fast = fast->next;

            slow = slow->next;

        }

        if(slow->next){

            slow->next = slow->next->next;

        }

        ListNode* ans = dummy->next;

        delete dummy;            

        return ans;

    }

};

解法2:

//统计链表长度:时间O(n),空间O(1)

class Solution {

public:

    int getLength(ListNode* head){

        int length = 0;

        while(head){

            ++length;

            head = head->next;

        }

        return length;

    }

    ListNode* removeNthFromEnd(ListNode* headint n) {

        ListNode* dummy = new ListNode(0,head);

        int length = getLength(dummy);

        ListNode* prev = dummy;

        for(int i=0;i<length-n-1;i++){

            prev = prev->next;

        }

        prev->next = prev->next->next;

        ListNode* ans = dummy->next;

        delete dummy;

        return ans;

    }

};

解法3:

//栈:时间O(n),空间O(n)

class Solution {

public:

    ListNode* removeNthFromEnd(ListNode* headint n) {

        if(head==nullptr || n==0){

            return nullptr;

        }

        ListNode *dummy = new ListNode(0,head);

        stack<ListNode*> stk;

        ListNode* cur = dummy;

        while(cur){

            stk.push(cur);

            cur = cur->next;

        }

        for(int i=0;i<n;i++){

            stk.pop();

        }

        ListNode* prev = stk.top();

        prev->next = prev->next->next;

        ListNode* ans = dummy->next;

        delete dummy;            

        return ans;

    }

};

 

 

21. 合并两个有序链表

难度简单

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

来自 <力扣>

 

题解:

// 方法一:迭代

class Solution {

public:

    ListNode* mergeTwoLists(ListNode* l1ListNode* l2) {

        ListNode *dummy = new ListNode(-1);

        ListNode *ans = dummy;

        //因为后面要比较大小,所以必须用&&确保l1和l2都存在元素。

        while(l1 && l2)

        {         

            if(l1->val < l2->val)

            {

                ans->next = l1;

                l1 = l1->next;

            }

            else

            {

                ans->next = l2;

                l2 = l2->next;

            }

            ans = ans->next;

        }

         ans->next = l1 ? l1:l2; 

         ans = ans->next;

        return dummy->next;

    }

};

//方法二:递归

class Solution {

public:

    ListNode* mergeTwoLists(ListNode* l1ListNode* l2) {

        if(!l1)

        {

            return l2;

        }else if(!l2)

        {

            return l1;

        }else if(l1->val < l2->val)

        {

            l1->next = mergeTwoLists(l1->next,l2);

            return l1;

        }else

        {

            l2->next = mergeTwoLists(l1, l2->next);

            return l2;

        }

    }

};

 

 

23. 合并K个升序链表

难度困难

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

来自 <力扣>

题解:

 //逐一合并: 空间O(1)

class Solution {

public:

    ListNode* mergeTwoLists(ListNode* l1,ListNode* l2){

        ListNode* dummy = new ListNode();

        ListNode* cur = dummy;

        while(l1&&l2)

        {

            if(l1->val<l2->val)

            {

                cur->next = l1;

                l1 = l1->next;

            }else{

                cur->next = l2;

                l2 = l2->next;

            }

            cur = cur->next;

        }

        cur->next = l1 ? l1 : l2;

        return dummy->next;

    }

    ListNode* merge(vector<ListNode*>& lists,int left,int right){

        if(left==right){

            return lists[left];

        }

        int mid = left + (right-left)/2;

        ListNode* l1 = merge(lists,left,mid);

        ListNode* l2 = merge(lists,mid+1,right);

        return mergeTwoLists(l1,l2);

    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {

        int num = lists.size();

        if(lists.empty()){

            return nullptr;

        }

        return merge(lists,0,num-1);

    }

};

//优先队列:空间O(1)

class Solution{

public:

    struct comp{

        bool operator()(ListNode* aListNode* b){

            return a->val > b->val;

        }

    };

    priority_queue<ListNode* , vector<ListNode*>, comp> q;

    ListNode* mergeKLists(vector<ListNode*>& lists) {

        for(auto node:lists){

            if(node){

                q.push(node);

            }

        }

        ListNode* head = new ListNode();

        ListNode* tail = head;

        while(!q.empty()){

            ListNode* node = q.top();

            q.pop();

            tail->next = node;

            tail = tail->next;

            if(node->nextq.push(node->next);

        }

        return head->next;

    }

};

 

24. 两两交换链表中的节点

难度中等

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

 

示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例 2:

输入:head = []
输出:[]

示例 3:

输入:head = [1]
输出:[1]

来自 <力扣>

题解:

 //时间O(n) 空间O(1)

 //一次平移两个结点,通过引入tmp结点交换两个节点指向,但需要记录前一个结点,将前一组的尾结点重新指向翻转后的头结点

class Solution {

public:

    ListNode* swapPairs(ListNode* head) {

        if(head==nullptr)

            return nullptr;

        if(head && head->next==nullptr)

            return head;

        ListNode* dummy = new ListNode(0,head);

        ListNode* cur = dummy; //dummy节点开始,cur指每两个中头结点的前一个结点

        while(cur->next && cur->next->next)

        {

            //交换两结点

            ListNode* tmp = cur->next->next;

            cur->next->next = tmp->next;

            tmp->next = cur->next;

            //将前一组的尾结点重新指向翻转后的头结点

            cur->next = tmp;

            cur = cur->next->next;

        }

        return dummy->next;

    }

};

 

25. K 个一组翻转链表

难度困难

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

 

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

来自 <力扣>

题解:

//反转子链表,K为一组反转,一组中起始结点为start,尾部结点为end,只要end不为空就反转此组链表。

 //反转前需要指定start前一个结点pre,也即上一组的反转后的尾结点(反转后尾结点已经变成start),还需指定end之后的结点next(也即下一组的start结点)

 //每次反转介绍后pre,start,end,next均指定对应位置即可

class Solution {

public:

    ListNode* reverse(ListNode* head){

        ListNode* pre = new ListNode(0);

        ListNode* cur = head;

        while(cur){

            ListNode* next = cur->next;

            cur->next = pre;

            pre = cur;

            cur = next;

        }

        return pre;

    }

    ListNode* reverseKGroup(ListNode* headint k) {

        ListNode* dummy = new ListNode(0,head);

        ListNode* pre = dummy;

        ListNode* end = dummy;

        while(end->next){

            for(int i=0;i<k&&end!=nullptr;i++) end = end->next;

            if(end==nullptrbreak;

            ListNode* next = end->next;

            ListNode* start = pre->next;

            end->next = nullptr;

            pre->next = reverse(start);

            start->next = next;

            pre = start;

            end = pre;

        }

        

        return dummy->next;

    }

};

 

61. 旋转链表

难度中等

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

 

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]

示例 2:

输入:head = [0,1,2], k = 4
输出:[2,0,1]

来自 <力扣>

 

题解:

//链表长度为len,如果k>len,只需移动k=k%len个位置,因为整数倍移动是没有变化的

 //找到倒数第k-1个位置结点cur,该结点与后面结点断开,即cur指向null,让cur的下一个结点变成头结点,即dummy结点指向cur的下一个结点,链表的尾结点要指向原先的头结点。

 //时间O(n),空间O(1)

class Solution {

public:

    ListNode* rotateRight(ListNode* headint k) {

        if(head==nullptr || k==0){

            return head;

        }

        ListNode* dummy = new ListNode(0,head);

        ListNode* cur = dummy;

        int len = 0;

        while(cur->next){

            len++;

            cur = cur->next;

        }

        //整数倍不需反转

        if(len==1 || k%len==0return head;

        if(k>len){

            k = k % len;

        }

        ListNode* tail = cur;

        cur = dummy;

        for(int i=0;i<len-k;i++){

            cur = cur->next;

        }

        dummy->next = cur->next;

        cur->next = nullptr;

        tail->next = head;

        return dummy->next;

    }

};

 

 

92. 反转链表 II

难度中等

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

 

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

 

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

来自 <力扣>

题解:

//固定left前面的一个结点pre,依次取下一个结点放到pre后,并改变指向,直到right结点

class Solution {

public:

    ListNode* reverseBetween(ListNode* headint leftint right) {

        ListNode *dummyNode = new ListNode(-1);

        dummyNode->next = head;

        ListNode *pre = dummyNode;

        for(int i=0; i<left-1; i++)

            pre = pre->next;

        ListNode *next;

        ListNode *cur = pre->next;

        for(int i=0; i<right-left;i++)

        {

            next = cur->next;

            cur->next = next->next;

            next->next = pre->next;

            pre->next = next;

        }

        return dummyNode->next;

    }

};

 

141. 环形链表

难度简单

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

 

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

来自 <力扣>

题解:

 //快指针走两步,慢指针走一步,相遇则有环

class Solution {

public:

    bool hasCycle(ListNode *head) {

        ListNode* fast = head;

        ListNode* slow = head;

        while(fast&&fast->next&&fast->next->next){

            fast = fast->next->next;

            slow = slow->next;

            if(fast == slow)

                return true;

        }

        return false;

        

    }

};

 

142. 环形链表 II

难度中等

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

 

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

来自 <力扣>

题解:

 //快慢指针相遇后,快指针回到头结点,快指针慢指针都走一步,再次相遇的地方就是入环结点

class Solution {

public:

    ListNode *detectCycle(ListNode *head) {

        ListNode* fast = head;

        ListNode* slow = head;

        bool flag = false;

        while(fast&&fast->next&&fast->next->next){

            fast = fast->next->next;

            slow = slow->next;

            if(fast==slow){

                flag = true;

                break;

            }

        }

        fast = head;

        if(flag){

            while(fast!=slow){                                

                slow = slow->next;

                fast = fast->next;

            }

            return fast;

        }else{

            return NULL;

        }    

    }

};

 

160. 相交链表

难度简单

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。 

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

来自 <力扣>

题解:

解法1:

//计算各自长度,长的链表多走差值,再同步走,走到最后若无相同结点则不相交,若有则相交

class Solution {

public:

    int getLen(ListNode* head){

        int len = 0;

        while(head){

            head=head->next;

            len++;

        }

        return len;

    }

    ListNode *getIntersectionNode(ListNode *headAListNode *headB) {

        int lenA = getLen(headA);

        int lenB = getLen(headB);

        if(lenA>lenB){

            for(int i=0;i<abs(lenA-lenB);i++){

                headA = headA->next;

            }

        }else if(lenA<lenB){

            for(int i=0;i<abs(lenA-lenB);i++){

                headB = headB->next;

            }

        }

        while(headA && headB){

            if(headA==headB)

                return headA;

            headA = headA->next;

            headB = headB->next;

            

        }

        return NULL;

    }

};

解法2:

//双指针

class Solution {

public:

    ListNode *getIntersectionNode(ListNode *headAListNode *headB) {

        if (headA == nullptr || headB == nullptr) {

            return nullptr;

        }

        ListNode *pA = headA, *pB = headB;

        while (pA != pB) {

            pA = pA == nullptr ? headB : pA->next;

            pB = pB == nullptr ? headA : pB->next;

        }

        return pA;

    }

};

 

328. 奇偶链表

难度中等

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

 

示例 1:

输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]

示例 2:

输入: head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4]

来自 <力扣>

题解:

//奇链表连奇链表,偶链表连偶链表,需要记录偶链表的头结点,奇链表的尾结点连偶链表头结点

class Solution {

public:

    ListNode* oddEvenList(ListNode* head) {

        if(head==nullptr)

        {

            return head;

        }

        ListNode *evenHead = head->next;

        ListNode *even = evenHead;

        ListNode *odd = head;

        while(even!=nullptr && even->next!=nullptr)

        {

            odd->next = even->next;

            odd = odd->next;

            even->next = odd->next;

            even = even->next;

            

        }

        odd->next = evenHead;

        return head;

    }

};

 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值