C++相交链表和反转链表详解
目录
- 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
- 思路
- 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
- 双指针思路
- 递归
- 总结
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
文章图片
思路
简单来说,就是求两个链表交点节点的 指针。 这里同学们要注意,交点不是数值相等,而是指针相等。
为了方便举例,假设节点元素数值相等,则节点指针相等。
看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点:
文章图片
我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图:
文章图片
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到焦点。
否则循环退出返回空指针。
/** * Definition for singly-linked list. * struct ListNode { *int val; *ListNode *next; *ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* curA=headA; ListNode* curB=headB; int lenA=0; int lenB=0; while(curA!=nullptr){// 求链表A的长度lenA++; curA=curA->next; }while(curB!=nullptr){// 求链表B的长度lenB++; curB=curB->next; }//现在的curA,curB已经指向最后一个节点了,需要重新指向头结点curA=headA; curB=headB; if(lenAnext; }while(lenB){// 遍历curA 和 curB,遇到相同则直接返回if(curA==curB)return curA; // return curA(val) 返回节点中的值,这个写法是错误的直接return curAcurA=curA->next; curB=curB->next; lenB--; } return nullptr; //没有交点则返回空}};
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
【C++相交链表和反转链表详解】输出:[2,1]
示例 3:
输入:head = []
输出:[]
双指针思路
首先判断链表是否为空,为空则返回nullptr。
接下来定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。 此时我们return pre指针就可以了,pre指针就指向了新的头结点。
/** * 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) {} * }; */class Solution {public:ListNode* reverseList(ListNode* head) {if(head==nullptr)//对空链表的判断return nullptr; ListNode* per=nullptr; ListNode* cur=head; ListNode* temp; //建立一个指针while(cur){//没必要写 while(cur!=nullptr),写了这个还要判断cur,会浪费时间,直接cur就可以temp=cur->next; //保存cur的下一个节点cur->next=per; //cur的下一个节点指向per,实现反转per=cur; //cur=per; 错误,是把cur的节点赋值给percur=temp; //temp=cur; 错误,是把temp(原来的cur->next)的节点赋值给cur}return per; }};
递归
/** * 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) {} * }; */class Solution {public:ListNode* reverse(ListNode* per,ListNode* cur){//返回的是一个链表,其返回值是指针if(cur==nullptr)//递归的终止条件return per; ListNode* temp=cur->next; cur->next=per; return reverse(cur,temp); // 调用要写return}ListNode* reverseList(ListNode* head) {if(head==nullptr) //链表判空return nullptr; return reverse(NULL,head); // 调用要写return}};
总结 本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- leetcode|leetcode 92. 反转链表 II
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- c++基础概念笔记
- 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气
- C++Primer之|C++Primer之 函数探幽
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- QML基础信息
- LeetCode|LeetCode 876. 链表的中间结点
- C++-类型转换