4.1刷题(链表)
1.203. 移除链表元素 - 力扣(LeetCode)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 如果头节点直接不存在
if (head == nullptr) {
return nullptr;
}
// 如果头节点存在但是要删除
ListNode* p = head;
while (head!=nullptr && head->val == val) {
head = head->next;
}
// 如果头节点不删除
ListNode* pre = head;
while (pre && pre->next) {
p = pre->next;
while (p && p->val == val) {
p = p->next;
pre->next = p;
}
pre = pre->next;
}
return head;
}
};
//使用带头结点的方法进行操作
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode dummy(0,head);
ListNode* cur=&dummy;
while(cur->next){
ListNode *now=cur->next;
if (now->val==val){
cur->next=now->next;
delete(now);
}else{
cur=cur->next;
}
}
return dummy.next;
}
};
2.206. 反转链表 - 力扣(LeetCode)
//带头节点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode dummy=ListNode(0);
ListNode* pre=head;
ListNode* cur=head;
while(pre){
cur=pre->next;
pre->next=dummy.next;
dummy.next=pre;
pre=cur;
}
return dummy.next;
}
};
//不带头节点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head== nullptr){
return head;
}
//1.initial
ListNode*cur=head;
ListNode*next=nullptr;
ListNode*pre=nullptr;
//2.开始遍历
while(cur){
next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
};
3.24. 两两交换链表中的节点 - 力扣(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) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode dummy=ListNode(0,head);
ListNode *node0=&dummy;
ListNode *node1=head;
while(node1 && node1->next){
ListNode *node2=node1->next;
ListNode *node3=node2->next;
//交换下一个点的信息
node0->next=node2;
node2->next=node1;
node1->next=node3;
//exchange and for
node0=node1;
node1=node3;
}
return dummy.next;
}
};
4.19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//0.增加一个头节点
ListNode dimmy=ListNode(0,head);
//1.首先遍历
ListNode*p=head;
int count=0;
while(p){
count++;
p=p->next;
}
//2.进行划分,找到前驱节点
count=count-n;
p=&dimmy;
while(count>0){
count--;
p=p->next;
}
//3.进行删除
//此时p为前驱节点
ListNode *temp=p->next;
p->next=temp->next;
delete(temp);
return dimmy.next;
}
};
5.面试题 02.07. 链表相交 - 力扣(LeetCode)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode*>cnt;
ListNode*temp=headA;
while(temp!=nullptr){
cnt.insert(temp);
temp=temp->next;
}
temp=headB;
while(temp!=nullptr){
if(cnt.count(temp)>0){
return temp;
}
temp=temp->next;
}
return nullptr;
}
};
//特别nb的双指针法
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *pA = headA, *pB = headB;
while(pA!=pB){
pA= pA==nullptr?headB:pA->next;
pB= pB==nullptr?headA:pB->next;
}
return pA;
}
};
双指针法详细解释见面试题 02.07. 链表相交 - 力扣(LeetCode)
6.141. 环形链表 - 力扣(LeetCode)
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==nullptr||head->next==nullptr){
return false;
}
ListNode*fast=head->next;
ListNode*slow=head;
while(fast!=slow){
if(fast==nullptr||fast->next==nullptr){
return false;
}
fast=fast->next->next;
slow=slow->next;
}
return true;
}
};
7.142. 环形链表 II - 力扣(LeetCode)
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode*fast=head;
ListNode*slow=head;
while(fast&&fast->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
//表明一定有环存在
slow=head;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return fast;
}
}
return nullptr;
}
};