初级算法-链表

文章目录

        • 删除链表中的节点
          • 题意:
          • 解:
          • 代码:
        • 删除链表的倒数第N个节点
          • 题意:
          • 解:
          • 代码:
        • 反转链表
          • 题意:
          • 解:
          • 代码:
        • 合并两个有序链表
          • 题意:
          • 解:
          • 代码:
        • 回文链表
          • 题意:
          • 解:
          • 代码:
        • 环形链表
          • 题意:
          • 解:
          • 代码:

删除链表中的节点

题意:

如题,不能访问头结点,给你的是需要删除的节点

解:

很神奇的一道题,由于是链表,且不能访问头结点(也就是不知道当前节点的前一个节点)所以并不能删除这个节点,只能把下一个节点的值给自己,删除下一个节点,开拓思维

代码:
#include
using namespace std;
struct ListNode
{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
void deleteNode(ListNode* node)
{
    node->val=node->next->val;
    node->next=node->next->next;
}
int main()
{
    
}

删除链表的倒数第N个节点

题意:

如题

解:

看了一下评论,快慢指针还是蛮有趣的,我第一时间想的是递归

代码:
#include
using namespace std;
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) {}
};
int dg(ListNode* now, int n)
{
    if(now->next==nullptr) return 1;//倒数第一个 
    int nown=1+dg(now->next,n);//倒数x+1个 
    if(nown==0) return -1;//如果返回了负一就一直保持,同时表示已经完成删除 
    if(nown==n+1)
    {
        now->next=now->next->next;
        return -1;//删除完成返回负一 
    }
    return nown;//这里是第x个 
}
ListNode* removeNthFromEnd(ListNode* head, int n)//递归法
{
   int ret=dg(head,n);
   //cout<next;//没删除,表示要删除的就是头结点 
}
/*
ListNode* removeNthFromEnd(ListNode* head, int n)//快慢指针法 
{
    ListNode* slow=head,* fast=head;
    for(int i=0;inext;
    if(fast==nullptr) return head->next;
    while(fast->next!=nullptr)
    {
        fast=fast->next;
        slow=slow->next;
    }
    slow->next=slow->next->next;
    return head;
}*/
int main()
{
    
}

反转链表

题意:

如题

解:

基本链表操作

代码:
#include
using namespace std;
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* dg(ListNode* &ans,ListNode* now)
{
    ListNode* temp;//插入位置 
    if(now->next!=nullptr)//有下一个 
    {
        temp=dg(ans,now->next);
    }
    //cout<val<next=nullptr;
        temp->next=now;
        temp=temp->next;
    }
    return temp;
}
ListNode* reverseList(ListNode* head)//递归 
{
    ListNode* ans=nullptr;
    if(head==nullptr) return nullptr;
    dg(ans,head);
    return ans;
}
/*
ListNode* reverseList(ListNode* head)//迭代 
{
    ListNode* ans=nullptr;
    if(head==nullptr) return ans;
    while(head!=nullptr)
    {
        ListNode* next=head->next;
        if(ans==nullptr)
        {
            ans=head;
            ans->next=nullptr;
        }
        else
        {
            head->next=ans;
            ans=head;
        }
        head=next;
    }
    return ans;
}*/
int main()
{
    
}

合并两个有序链表

题意:

如题

解:

基本链表操作

代码:
#include
using namespace std;
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* mergeTwoLists(ListNode* list1, ListNode* list2)
{
    ListNode* ans=nullptr,* myinserter=nullptr;
    while(list1!=nullptr && list2!=nullptr)
    {
        ListNode* now=( (list1->valval) ?list1:list2);
        if(ans==nullptr)
        {
            ans=now;
            myinserter=ans;
        }
        else
        {
            myinserter->next=now;
            myinserter=myinserter->next;
        }
        now==list1?list1=list1->next:list2=list2->next;
    }
    if(list1!=nullptr)
    {
        if(ans==nullptr) ans=list1;
        else myinserter->next=list1;
    }
    else if(list2!=nullptr)
    {
        if(ans==nullptr) ans=list2;
        else myinserter->next=list2;
    }
    /*
    while(list1!=nullptr)
    {
        if(ans==nullptr)
        {
            ans=list1;
            myinserter=ans;
        }
        else
        {
            myinserter->next=list1;
            myinserter=myinserter->next;
        }
        list1=list1->next;
    }
    while(list2!=nullptr)
    {
        if(ans==nullptr)
        {
            ans=list2;
            myinserter=ans;
        }
        else
        {
            myinserter->next=list2;
            myinserter=myinserter->next;
        }
        list2=list2->next;
    }*/
    return ans;
}
int main()
{
    
}

回文链表

题意:

判断一个链表是否是回文

解:

O(n) 时间复杂度和 O(1) 空间复杂度,双指针+递归

代码:
#include
using namespace std;
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) {}
};
bool dg(ListNode* back,ListNode* &front)
{
    bool ans=true;
    if(back->next!=nullptr) ans=dg(back->next,front);
    if(ans==false) return false;//一个不满足就退出
    
    if(front->val==back->val)
    {
        front=front->next;
        return true;
    }
    return false;
}
bool isPalindrome(ListNode* head)
{
    bool ans=dg(head,head);
    return ans;
}
int main()
{
    
}

环形链表

题意:

判断链表中是否有环

解:

暴力法很润

有个翻转法也很有意思写了一下

有意思的是,当使用判断条件 if(oldhead==newhead||newhead->next==nullptr) return true;时,WA21/23,输入是[1] -1,返回true,答案false;

但是使用if(oldhead==newhead||newhead->next!=nullptr) return true;时,WA13/23,一样的输入,一样的输出,一样的答案,不太懂两个一样输出的怎么案例数不一样

当然,正确代码是if(oldhead==newhead&&newhead->next!=nullptr) return true;,当翻转完新的头结点和旧的头结点是同一个,且新的头结点还有指向时,链表存在环

代码:
#include
using namespace std;
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) {}
};
bool hasCycle(ListNode *head)//翻转法 
{
    if(head==nullptr) return false;
    ListNode* newhead=nullptr,* oldhead=head;
    for(;head!=nullptr;)
    {
        ListNode* temp=head->next;
        head->next=newhead;
        newhead=head;
        head=temp;
    }
    if(oldhead==newhead&&newhead->next!=nullptr) return true;
    return false;
}
/*
bool hasCycle(ListNode *head)//暴力法 
{
    if(head==nullptr) return false;
    int n=0;
    while(head->next!=nullptr)
    {
        head=head->next;
        n++;
        if(n>10007) return true;
    }
    return false;
}*/
int main()
{
    
}

你可能感兴趣的:(力扣每日一题,算法,链表,数据结构,leetcode,c++)