题目链接
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2: 输入:head = [], val = 1 输出:[]
示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]
class Solution {
public:
ListNode *removeElements(ListNode *head, int val) {
//链表一般要单独处理一下头节点
//处理头节点
while (head && head->val == val) {
ListNode *tmp = head;
head = head->next;
delete tmp;
}
//非头结点
ListNode *cur = head;
while (cur && cur->next) {
if (cur->next->val == val) {
ListNode *tmp = cur->next;
cur->next = tmp->next;
delete tmp;
} else {
cur = cur->next;
}
}
return head;
}
};
题目链接
题意:
在链表类中实现这些功能:
// 最好是新tmp节点存储头节点 无论头节点是否是真实的值
class MyLinkedList {
private:
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) {}
};
ListNode *_head;
int _size;
public:
MyLinkedList() {
_head = new ListNode();//这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
_size = 0;
}
int get(int index) {
if (index > _size - 1 || index < 0)return -1;
ListNode *cur = _head->next;
while (index--)
cur = cur->next;
return cur->val;
}
void addAtHead(int val) {
ListNode *cur = new ListNode(val);
cur->next=_head->next;
_head->next=cur;
++_size;
}
void addAtTail(int val) {
ListNode *cur = new ListNode(val, nullptr);
ListNode *tmp = _head;
while (tmp->next)
tmp = tmp->next;
tmp->next = cur;
++_size;
}
void addAtIndex(int index, int val) {
if (index < 0 || index > _size )return;
ListNode *cur = new ListNode(val, nullptr);
ListNode *tmp = _head;
while (index--)
tmp = tmp->next;
cur->next=tmp->next;
tmp->next=cur;
++_size;
}
void deleteAtIndex(int index) {
if(index<0||index>=_size)return;
ListNode*cur = _head;
while (index--)
cur=cur->next;
ListNode*tmp = cur->next;
cur->next = tmp->next;
--_size;
delete tmp;
}
void print(){
ListNode*cur = _head;
while (cur->next){
cout<< cur->next->val <<endl;
cur = cur->next;
}
}
};
题目链接
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
class Solution {
public:
ListNode *reverseList(ListNode *head) {
if (head == nullptr || head->next == nullptr)return head;
ListNode *pre = head, *cur = head->next, *tmp = head;
pre->next = nullptr;
while (cur) {
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
head = pre;
return head;
}
};
//另外一个版本
class Solution {
public:
ListNode *reverseList(ListNode *head) {
ListNode *pre = nullptr, *cur = head, *tmp = nullptr;
while (cur) {
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
head = pre;
return head;
}
};
题目链接
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode*f_head = new ListNode(0,head);
ListNode*cur=f_head;
while (cur->next&&cur->next->next){
ListNode*t1 = cur->next;
ListNode*t2 = cur->next->next->next;
cur->next=cur->next->next;
cur->next->next = t1;
t1->next=t2;
cur = cur->next->next;
}
return f_head->next;
}
};
题目链接
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
先求出链表的长度,然后根据给定的倒数第几个删除
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*f_head = new ListNode(0,head);
ListNode*cur = head;
int len{0};
while (cur){
cur=cur->next;
++len;
}
cur = f_head;
int cha = len-n;
while (cha--)
cur=cur->next;
cur->next=cur->next->next;
return f_head->next;
}
};
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*f_head = new ListNode(0,head);
ListNode*fast = f_head,*slow = f_head;
int step = n+1;
while (step--)
fast=fast->next;
while (fast){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return f_head->next;
}
};
题目链接
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
相交指的是地址相同,此题目如果相交那么在交点之后的所有地址都是相同的,也就是说第一个地址相同的节点必然是之后全部相交的
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p1 = headA, *p2 = headB;
int a_len{0}, b_len{0};
while (p1) {
p1 = p1->next;
++a_len;
}
while (p2) {
p2 = p2->next;
++b_len;
}
p1=headA;
p2=headB;
int gap_len = a_len-b_len;
if(gap_len){//A长
while (gap_len--)
p1=p1->next;
} else{
gap_len=-gap_len;
while (gap_len--)
p2=p2->next;
}
while (p1&&p2){
if(p1==p2){
return p1;
} else{
p1=p1->next;
p2=p2->next;
}
}
return nullptr;
}
};
题目链接
题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
第一问:判断是否有环?快慢指针
快指针一次两个节点,慢指针一次一个节点 其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode*slow=head,*fast=head;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
//快慢指针相遇
if(fast==slow){
slow = head;
while(slow!=fast){
slow=slow->next;
fast=fast->next;
}
return fast;
}
}
return nullptr;
}
};