leetcode 83 删除排序链表中的重复元素
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例 1:
输入:head = [1,1,2]
输出:[1,2]
示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]
代码如下:
/**
* 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* deleteDuplicates(ListNode* head) {
if(head==nullptr)
{
return nullptr;
}
ListNode* cur=head;
while(cur && cur->next)
{
if(cur->val==cur->next->val)
{
cur->next=cur->next->next;
}
else
{
cur=cur->next;
}
}
return head;
}
};
leetcode移除链表元素
题述:
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例二:
输入:head = [], val = 1
输出:[]
示例三:
输入:head = [7,7,7,7], val = 7
输出:[]
我们可以设置一个虚头结点,方便操作,这样原链表的所有节点就都可以按照统一的方式进行移除了。
C++代码如下:
/**
* 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* removeElements(ListNode* head, int val) {
ListNode* VirtualHead=new ListNode(0);
VirtualHead->next=head;
ListNode* cur=VirtualHead;
if(head==nullptr)
{
return nullptr;
}
while(cur->next)
{
if(cur->next->val==val)
{
ListNode* tmp=cur->next; //记录值为val的结点
cur->next=cur->next->next;
delete tmp;
}
else
{
cur=cur->next;
}
}
return VirtualHead->next;
delete VirtualHead;
}
};
leetcode 707设计链表
题述:
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
在链表类中实现这些功能:
class MyLinkedList {
public:
struct LinkedNode
{
int val;
LinkedNode* next;
LinkedNode(int val)
:val(val)
,next(nullptr)
{
}
};
MyLinkedList()
{
_VairtualHead=new LinkedNode(0);
_size=0;
}
int get(int index)
{
if(index>(_size-1)||index<0)
{
return -1;
}
LinkedNode* cur=_VairtualHead->next;
while(index--)
{
cur=cur->next;
}
return cur->val;
}
void addAtHead(int val)
{
LinkedNode* newNode=new LinkedNode(val);
newNode->next=_VairtualHead->next;
_VairtualHead->next=newNode;
_size++;
}
void addAtTail(int val)
{
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=_VairtualHead;
while(cur->next)
{
cur=cur->next;
}
cur->next=newNode;
_size++;
}
void addAtIndex(int index, int val)
{
if(index>_size)
{
return ;
}
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=_VairtualHead;
while(index--)
{
cur=cur->next;
}
newNode->next=cur->next;
cur->next=newNode;
_size++;
}
void deleteAtIndex(int index)
{
if(index>=_size || index<0)
{
return ;
}
LinkedNode* cur=_VairtualHead;
while(index--)
{
cur=cur->next;
}
LinkedNode* tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
_size--;
}
private:
int _size;
LinkedNode* _VairtualHead;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
leetcode 206反转链表
题述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
输入:head = [1,2]
输出:[2,1]
示例三:
输入:head = []
输出:[]
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为nullprt。
然后就要开始反转了,首先要把 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) {
ListNode* cur=head;
ListNode* pre=nullptr;
while(cur)
{
ListNode* tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
return pre;
}
};
leetcode 24.两两交换链表中的结点
题述:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
分析:
初始时,cur指向虚拟头结点,然后进行如下三步:
操作之后,链表如下:
直观图:
代码如下:
/**
* 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* swapPairs(ListNode* head) {
ListNode *VirtualHead=new ListNode(0);
VirtualHead->next=head;
ListNode* cur=VirtualHead;
while(cur->next && cur->next->next)
{
ListNode* tmp=cur->next;
ListNode* tmp1=cur->next->next->next;
cur->next=cur->next->next; //步骤一
cur->next->next=tmp; //步骤二
cur->next->next->next=tmp1; //步骤三
cur=cur->next->next; //跳两步
}
return VirtualHead->next;
delete VirtualHead;
}
};
leetcode 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]
思路:
双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
思路是这样的,但要注意一些细节。
分为如下几步:
代码如下:
/**
* 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* removeNthFromEnd(ListNode* head, int n) {
ListNode* VirtualHead=new ListNode(0);
VirtualHead->next=head;
ListNode* slow=VirtualHead;
ListNode* fast=VirtualHead;
//fast先走
while(fast->next && n--)
{
fast=fast->next;
}
fast=fast->next;
while(fast)
{
slow=slow->next;
fast=fast->next;
}
slow->next=slow->next->next;
return VirtualHead->next;
delete VirtualHead;
}
};
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
题目数据 保证 整个链式结构中不存在环。
**注意,**函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。
分析:
简单来说,就是求两个链表交点节点的指针。 这里要注意,交点不是数值相等,而是指针相等。
我们求出两个链表的长度,并求出两个链表长度的差值,然后让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)
{
lenA++;
curA=curA->next;
}
while(curB)
{
lenB++;
curB=curB->next;
}
//再将cur指向head
curA=headA;
curB=headB;
if(lenA<lenB)
{
swap(curA,curB);
swap(lenA,lenB);
}
int gap=lenA-lenB;
//lenA先走
while(gap--)
{
curA=curA->next;
}
while(curA)
{
if(curA==curB)
{
return curA;
}
else
{
curA=curA->next;
curB=curB->next;
}
}
return nullptr;
}
};
leetcode 142.环形链表II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
说明:不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
分析:
可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
为什么fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇呢,而不是永远的错开呢
首先第一点:fast指针一定先进入环中,如果fast指针和slow指针相遇的话,一定是在环中相遇,这是毋庸置疑的。
那么来看一下,为什么fast指针和slow指针一定会相遇呢?
可以画一个环,然后让 fast指针在任意一个节点开始追赶slow指针。
因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
如果有环,如何找到这个环的入口
此时已经可以判断链表是否有环了,那么接下来要找这个环的入口了。
假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。 如图所示:
那么相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。
因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:
(x + y) * 2 = x + y + n (y + z)
两边消掉一个(x+y): x + y = n (y + z)
因为要找环形的入口,那么要求的是x,因为x表示 头结点到 环形入口节点的的距离。
所以要求x ,将x单独放在左面:x = n (y + z) - y ,
再从n(y+z)中提出一个 (y+z)来,整理公式之后为如下公式:x = (n - 1) (y + z) + z 注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。
这个公式说明什么呢?
先拿n为1的情况来举例,意味着fast指针在环形里转了一圈之后,就遇到了 slow指针了。
当 n为1的时候,公式就化解为 x = z,
这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
也就是在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。
让index1和index2同时移动,每次移动一个节点, 那么他们相遇的地方就是 环形入口的节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
// 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
if(slow==fast)
{
ListNode* index1=head;
ListNode* index2=fast;
while(index1!=index2) //当没有相遇时
{
index1=index1->next;
index2=index2->next;
}
//相遇时
return index2; //也可以返回index1,毕竟两个结点相遇了。
}
}
return nullptr;
}
};
leetcode 21 合并两个有序的链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
/**
* 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* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* VirtualHead=new ListNode(0);
ListNode* cur=VirtualHead;
ListNode* cur1=list1;
ListNode* cur2=list2;
while(cur1 && cur2)
{
if(cur1->val<cur2->val)
{
cur->next=cur1;
cur1=cur1->next;
}
else
{
cur->next=cur2;
cur2=cur2->next;
}
cur=cur->next;
}
//若cur1剩余结点
if(cur1)
{
cur->next=cur1;
}
//若cur2剩余结点
if(cur2)
{
cur->next=cur2;
}
return VirtualHead->next;
delete VirtualHead;
}
};
leetcode 143.重排链表
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]
输出:[1,4,2,3]
示例 2:
输入:head = [1,2,3,4,5]
输出:[1,5,2,4,3]
分析:申请一个数组,直接将结点复制在数组中,进行操作
代码如下:
/**
* 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:
void reorderList(ListNode* head) {
vector<ListNode*> vec;
ListNode* cur=head;
if(cur==nullptr)
{
return ; //终止程序,不是返回空指针。
}
while(cur)
{
vec.push_back(cur);
cur=cur->next;
}
cur=head;
int count=0; //作用是根据计数的奇偶进行重排
int left=1;
int right=vec.size()-1;
while(left<=right)
{
if(count%2==0)
{
cur->next=vec[right--];
cur=cur->next;
}
else
{
cur->next=vec[left++];
cur=cur->next;
}
count++;
}
cur->next=nullptr;
}
};
leetcode 86分割链表
题述:
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
示例 2:
输入:head = [2,1], x = 2
输出:[1,2]
分析: 首先根据题目中给的特定值x,然后将链表分割成结点值val小于x的一个链表和节点值val大于等于x值得链表。
/**
* 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* partition(ListNode* head, int x) {
ListNode* headA=new ListNode(0);
ListNode* headB=new ListNode(0);
ListNode* curA=headA;
ListNode* curB=headB;
ListNode* cur=head;
while(cur)
{
if(cur->val<x)
{
curA->next=cur;
curA=curA->next;
}
else
{
curB->next=cur;
curB=curB->next;
}
cur=cur->next;
}
curA->next=headB->next;
curB->next=nullptr;
delete headB;
return headA->next;
delete headA;
}
};
leetcode 234. 回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
输入:head = [1,2]
输出:false
分析: 可以将结点值放入数组中,进行判断回文(左右指针思想)
ListNode *cur=head;
int count=0;
//计算结点数
while(cur)
{
count++;
cur=cur->next;
}
vector<int> vec;
vec.resize(count,0);
int i=0;
cur=head;
while(cur)
{
vec[i++]=cur->val;
cur=cur->next;
}
int left=0;
int right=count-1;
while(left<=right)
{
if(vec[left]!=vec[right])
{
return false;
}
else
{
left++;
right--;
}
}
return true;
leetcode 148排序链表
题述:
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
/**
* 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* sortList(ListNode* head) {
if(head==nullptr)
{
return nullptr;
}
vector<int> vec;
ListNode* cur=head;
while(cur)
{
vec.push_back(cur->val);
cur=cur->next;
}
cur=head;
sort(vec.begin(),vec.end());
int i=0;
//int *p=&vec[0];
while(cur)
{
cur->val=vec[i++];
//cur->val=*p;
cur=cur->next;
// *p++;
}
return head;
}
};
题述:
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 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 = [[]]
输出:[]
分析: 本题借助了 leetcode 148排序链表 的思想
代码如下:
/**
* 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* sortList(ListNode* head) {
if(head==nullptr)
{
return nullptr;
}
ListNode* cur=head;
vector<int> vec;
while(cur)
{
vec.push_back(cur->val);
cur=cur->next;
}
sort(vec.begin(),vec.end());
cur=head;
//int *p=&vec[0];
int i=0;
while(cur)
{
cur->val=vec[i++];
cur=cur->next;
//p++;
}
return head;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
int size=lists.size();
vector<int> vec;
for(int i=0;i<size;i++)
{
ListNode* cur=lists[i];
while(cur)
{
vec.push_back(cur->val);
cur=cur->next;
}
}
int len=vec.size();
ListNode* VirtualHead=new ListNode(0);
ListNode* cur1=VirtualHead;
for(int i=0;i<len;i++)
{
ListNode* newNode=new ListNode(vec[i]);
cur1->next=newNode;
cur1=newNode;
}
cur1->next=nullptr;
sortList(VirtualHead->next);
return VirtualHead->next;
delete VirtualHead;
}
};
leetcode 876.链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
/**
* 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* middleNode(ListNode* head) {
if(head==nullptr)
{
return nullptr;
}
ListNode* slow=head;
ListNode* fast=head;
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
};
leetcode 2. 两数相加
题述:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入: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]
代码如下:
/**
* 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* VirtualHead=new ListNode(0);
ListNode* cur=VirtualHead;
ListNode* cur1=l1;
ListNode* cur2=l2;
int carry=0;
while(cur1 || cur2 || carry)
{
if(cur1)
{
carry+=cur1->val;
}
if(cur2)
{
carry+=cur2->val;
}
ListNode* tmp=new ListNode(carry%10);
cur->next=tmp;
cur=cur->next;
if(cur1)
{
cur1=cur1->next;
}
if(cur2)
{
cur2=cur2->next;
}
carry=carry/10;
}
cur->next=nullptr;
return VirtualHead->next;
delete VirtualHead;
}
};
声明:本文主要参考卡尔哥的算法思想,整理是自己复习,不作为任何商业传播意图。感谢卡尔哥!!!