链表问题

链表问题:

涉及头节点的需要设计虚拟头节点来完成

//删除链表的倒数第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问题进行总结和复习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值