链表问题:
涉及头节点的需要设计虚拟头节点来完成
//删除链表的倒数第N个节点,采用两个指针来完成判断
/**
* 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*root=new ListNode(0,head);
ListNode*l=root,*r=head;
for(int i=0;i<n;i++){
r=r->next;
}
while(r!=nullptr){
l=l->next;
r=r->next;
}
l->next=l->next->next;
return root->next;
}
};
//两两交换两链表
/**
* 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*root=new ListNode(0,head);
ListNode*t=root;
while(t->next!=nullptr&&t->next->next!=nullptr){
ListNode*l=t->next;
ListNode*r=t->next->next;
l->next=r->next;
r->next=l;
t->next=r;
t=l;
}
return root->next;
}
};
//删除排序链表中的重复元素,此处不涉及头节点,无需虚拟头节点
/**
* 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 head;
ListNode*p=head;
while(p->next!=nullptr){
if(p->next->val==p->val){
p->next=p->next->next;
}else{
p=p->next;
}
}
return head;
}
};
//删除排序链表的重复元素2
/**
* 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||head->next==nullptr){
return head;
}
ListNode*root=new ListNode(0,head);
ListNode*l=root;
while(l->next!=nullptr){
ListNode*r=l->next->next;
while(r!=nullptr&&r->val==l->next->val){
r=r->next;
}
if(r==l->next->next){//没删元素
l=l->next;
}else{
l->next=r;//删了元素
}
}
return root->next;
}
};
环形链表问题:
1、 快慢指针法判断
//判断是否有环
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==nullptr) return false;
ListNode*slow=head,*fast=head;
while(fast!=nullptr&&fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
if(fast==slow) {
/*slow=head;
while(slow!=fast){
slow=slow->next;
fast=fast->next;
}
跳出循环后的slow即为环的入口
*/
return true;
}
}
return false;
}
};
相交链表
/**
* 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) {
if(headA==nullptr||headB==nullptr){
return nullptr;
}
ListNode*a=headA,*b=headB;
int f=0;
while(1){
if(a==b){
return a;
}
if(a->next==nullptr){
a=headB;
f++;
}else{
a=a->next;
}
if(b->next==nullptr){
b=headA;
f++;
}else{
b=b->next;
}
if(f>2){
break;
}
}
return nullptr;
}
};
//环形链表变体
//快乐数202
class Solution {
public:
int num[10]={0,1,4,9,16,25,36,49,64,81};
int func(int x){
int t=0;
while(x){
t+=num[x%10];
x/=10;
}
return t;
}
bool isHappy(int n) {
int slow=n,fast=n;
while(1){
fast=func(fast);
fast=func(fast);
slow=func(slow);
if(fast==1){
break;
}
if(fast==slow){
return false;
}
}
return true;
}
};
//203 移除链表元素
/**
* 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) {
if(head==nullptr) return head;
ListNode*root=new ListNode(0,head);
ListNode*l=root;
while(l!=nullptr&&l->next!=nullptr){
ListNode*r=l->next;
while(r!=nullptr&&r->val==val){
r=r->next;
}
l->next=r;
l=l->next;
}
return root->next;
}
};
//206反转链表
/**
* 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||head->next==nullptr){
return head;
}
ListNode*l=head,*r=head->next;
l->next=nullptr;
while(r!=nullptr){
ListNode*t=r->next;
r->next=l;
l=r;
r=t;
}
return l;
}
};
//237 删除链表中的节点O(1)
借尸还魂
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
栈的问题:
//判断入栈序列和出栈序列是否匹配
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
int n,num[15],out[15];
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>num[i];
}
for(int j=0;j<n;j++){
cin>>out[j];
}
stack<int>sta;
for(int i=0,j=0;i<n;i++){
while(sta.empty()||sta.top()!=out[i]){
if(j==n){
cout<<"NO"<<endl;
return 0;
}
sta.push(num[j]);
j++;
}
sta.pop();
}
cout<<"YES"<<endl;
return 0;
}
//844比较含退格的字符串
class Solution {
public:
bool backspaceCompare(string s, string t) {
stack<char>s1,s2;
for(auto c:s){
if(c=='#'){
if(!s1.empty()){
s1.pop();
}
}else{
s1.push(c);
}
}
for(auto c:t){
if(c=='#'){
if(!s2.empty()){
s2.pop();
}
}else{
s2.push(c);
}
}
while(!s1.empty()&&!s2.empty()){
if(s1.top()!=s2.top()){
return false;
}
s1.pop();
s2.pop();
}
if(s1.empty()&&s2.empty()){
return true;
}
return false;
}
};
//1047删除字符串中的所有重复相邻重复项
class Solution {
public:
string removeDuplicates(string s) {
stack<char>sta;
for(auto c:s){
if(sta.empty()||sta.top()!=c){
sta.push(c);
}else{
sta.pop();
}
}
string ans;
while(!sta.empty()){
ans+=sta.top();
sta.pop();
}
reverse(ans.begin(),ans.end());
return ans;
}
};
剑指 Offer 35. 复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr) return nullptr;
unordered_map<Node*,Node*>mp;
Node* temp=new Node(0);
Node*cur=head,*pre=temp;
while(cur){
Node*temp1=new Node(cur->val);
pre->next=temp1;
mp[cur]=temp1;
pre=pre->next;
cur=cur->next;
}
for(auto&[key,value]:mp){
value->random=key->random==nullptr?nullptr:mp[key->random];
}
delete temp;
return mp[head];
}
};
//节省空间
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr) return nullptr;
Node*cur=head;
while(cur){
Node*temp=new Node(cur->val);
temp->next=cur->next;
cur->next=temp;
cur=temp->next;
}
//Node*old=head,*nnew=head->next;
cur=head;
while(cur){
cur->next->random=cur->random==nullptr?nullptr:cur->random->next;
cur=cur->next->next;
}
Node* h1=head->next;
Node* h2=head;
Node* myHead=h1;
while(h2){
h2->next=h1->next;
h2=h2->next;
h1->next=h2==nullptr?nullptr:h2->next;
h1=h1->next;
}
return myHead;
}
};
rand5实现rand7
int main(){
int x=~(1<<31);//取最大的int\\
while(x>21){
x=(rand5()-1)*5+rand5();
}
return x%7+1;
}
学习产出:
对链表和栈的leetcode问题进行总结和复习