链表的相关面试题(完整)(C语言)

链表的相关面试题

  • 我这里是单链表,并且带头结点,其实我感觉带不带头结点都无所谓了。只要思路是正确的,那么代码实现起来相对简单。
链表的基本操作
  • 我的头文件中的一些定义
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;
#define Max 100

typedef struct Node  //一般链表的定义
{
    DataType data;
    struct Node* next;
}Node, *pNode, List, *pList;

typedef struct ComplexNode   //定义复杂链表,一个链表的每个节点,有一个指向next指针指向下一个节点,
   //还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
{
    DataType _data;
    struct ComplexNode* _next;
    struct ComplexNode* _random;
}ComplexNode;
  • 这些是我的单链表中的基本操作,(增删查改)
void InitLinkList(pList* pplist);  //初始化
void DestroyLinkList(pList* pplist);  //删除
void PushBack(pList* pplist, DataType d); //尾插
void PrintLinkList(pList plist); //显示
void PopBack(pList* pplist);  //尾删
int GetListLength(pList head);//链表长度
void PushFront(pList *pplist, DataType x);//头插
void PopFront(pList *pplist);//头删
pList Find(pList plist, DataType d);//查找
  • 这里是链表的一些面试题
void Insert(pList *pplist, int pos, DataType d);//插入
void Remove(pList *pplist, DataType d);//移除链表中指定元素的第一个
void RemoveAll(pList *pplist, DataType x);//移除链表中所有指定元素
void Erase(pList *pplist,int pos);//删除指定位置的元素
void PrintTailToHead(pList *pplist);//从尾到头打印单链表
void ReverseList(pList* pplist);//逆置/反转单链表
void BubbleSort(pList * pplist);//单链表排序(冒泡排序)
int Size(pList plist);  //大小
int FindMidNode(pList plist);//查找单链表的中间节点,要求只能遍历一次链表
int DelLastKNode(pList plist, int k); //查找单链表的倒数第k个节点,要求只能遍历一次链表
int pLinkNodeJosephCycle(pList * pplist, int num); //单链表实现约瑟夫环
void EraseNotTail(pList pos);//删除一个无头单链表的非尾节点
void InsertNode(pList pos);//在无头单链表的一个节点前插入一个节点
pList pLinkNodeMerge(pList plist1, pList plist2); //合并两个有序链表, 合并后依然有序
void UnionSet(pList* plist1, pList* plist2);  //求两个有序单链表交集(差集)
pList CheckCycleandLength(pList plist);//判断单链表是否带环?若带环,求环的长度?求环的入口点?
void CheckNoCross(pList list1, pList list2);////判断两个链表是否相交,若相交,求交点。(链表不带环)
pList CheckHaveCross(pList list1, pList list2);//判断两个链表是否相交,若相交,求交点。(链表带环)
ComplexNode * BuyComplexNode(DataType x);// 创建一个复杂链表的结点
void Display(const ComplexNode * cplist);//打印复杂的单链表
ComplexNode * CopyComplexNode(ComplexNode * cplist);//复杂链表的复制
  • 初始化我的链表,给链表申请一个头结点
void InitLinkList(pList* pplist)
{
    pList head=NULL;  //头结点
    head = (pList)malloc(sizeof(List));
    head->next = NULL;
    (*pplist) = head;
    return;
}
  • 清空链表中所有节点,需要一个节点一个节点的删除。
void DestroyLinkList(pList* pplist)
{
    pList stmp = NULL;
    pList etmp = NULL;
    stmp = *pplist;
    etmp = stmp;
    if ((*pplist) == NULL)
    {
        printf("链表为空\n");
    }
    else
    {
        while (etmp != NULL)
        {
            stmp = stmp->next;
            free(etmp);
            etmp = NULL;
            etmp = stmp;
        }
        printf("删除链表成功!\n");
    }
    (*pplist)->next = NULL;
    return;
}
  • 尾插一个节点,先找到链表的最后一个节点,然后在加新的节点
void PushBack(pList* pplist, DataType d)
{
    pList Add = NULL;
    pList tmp = NULL;
    tmp = (pList)malloc(sizeof(List));
    tmp = (*pplist);
    Add = (pList)malloc(sizeof(List));
    Add->data = d;
    Add->next = NULL;
    if (tmp->next == NULL)
    {
        tmp->next = Add;
    }
    else
    {
        while (tmp != NULL)
        {
            if (tmp->next == NULL)
            {
                tmp->next = Add;
                break;
            }
            tmp = tmp->next;
        }
    }
    return;
}
  • 打印链表的节点
void PrintLinkList(pList plist)
{
    pList tmp = NULL;
    tmp = plist;
    tmp = tmp->next;
    if (tmp == NULL)
    {
        printf("链表为空\n");
        return;
    }
    while (tmp)
    {
        printf("%d  ", tmp->data);
        tmp = tmp->next;
    }
    printf("\n");
}
  • 尾删链表的节点
void PopBack(pList* pplist)  //尾删
{
    pList tmp = NULL;
    tmp = (*pplist);
    if (tmp->next == NULL) //无节点
    {
        printf("链表为空\n");
        return;
    }
    else if (tmp->next->next == NULL)
    {
        free(tmp->next);
        tmp->next = NULL;
        return;
    }
    else
     {
        while (tmp->next->next != NULL)  //二个以上节点的删除
        {
            tmp= tmp->next;
        }
        free(tmp->next->next);
        tmp->next = NULL; 
     }
}
  • 求链表的长度
int GetListLength(pList plist)
{  //不需要断言  链表可以为空
    int len = 0;
    while (plist->next != NULL)
    {
        plist = plist->next;
        len++;
    }
    return len;
}
  • 在链表中头插一个节点
void PushFront(pList *pplist, DataType d)
{
    assert(pplist);
    pList Add = NULL;
    pList tmp = NULL;
    tmp = (*pplist);
    Add = (pList)malloc(sizeof(List));
    Add->data = d;

    Add->next = tmp->next;
    tmp->next = NULL;
    tmp->next = Add;
}
  • 在链表中头删一个节点
void PopFront(pList* pplist) 
{
    assert(pplist);
    pList tmp = NULL;
    pList p = NULL;
    tmp = (*pplist);
    if (tmp->next == NULL)
    {
        return;
    }
    else if (tmp->next->next == NULL)
    {
        free(tmp->next);
        tmp->next = NULL;
    }
    else
    {
        p = tmp->next->next;
        free(tmp->next);
        tmp->next = NULL;
        tmp->next = p;
    }
}
  • 在链表中查找节点
pList Find(pList plist, DataType d)
{
    while (plist)
    {
        if (d == plist->data)
        {
            printf("找到了");
            return plist;
        }
        plist = plist->next;
    }
    return NULL;
}
  • 在链表中指定位置插入一个节点
void Insert(pList *pplist, int pos, DataType d)
{
    pList tmp = NULL;
    pList Add = NULL;
    Add = (pList)malloc(sizeof(List));
    Add->data = d;
    Add->next = NULL;
    tmp = (*pplist);
    if (pos <= 0 || pos > Size(*pplist))
    {
        printf("位置有误\n");
        return;
    }
    if (tmp->next == NULL)
    {
        printf("空链表");
        return;
    }
    else if (tmp->next->next == NULL)
    {
        PushFront(pplist, d);
    }
    else
    {
        for (int i = 1; i < pos ; i++)  
        {
            tmp = tmp->next;
        }
        Add->next = tmp->next;
        tmp->next = NULL;
        tmp->next = Add;
    }
}
  • 删除链表中指定元素的第一个
void Remove(pList *pplist, DataType d)
{
    assert(pplist);
    pList tmp = NULL;
    pList smp = NULL;
    tmp = (*pplist);
    if (tmp->next == NULL)
    {
        printf("空链表\n");
        return;
    }
    else if ( tmp->next->next == NULL && d == tmp->next->data)
    {
        free(tmp->next);
        tmp->next = NULL;
    }
    else
    {
        while (tmp->next->next != NULL)
        {
            if (d == tmp->next->data)
            {
                smp = tmp->next->next;
                free(tmp->next);
                tmp->next = NULL;
                tmp->next = smp;
                return;
            }
            tmp = tmp->next;
        }
    }
}
  • 删除链表中所有指定元素
void RemoveAll(pList *pplist, DataType d)
{
    pList tmp = NULL;
    pList smp = NULL;
    tmp = (*pplist);
    while (tmp->next->next != NULL)
    {
        if (d == tmp->next->data)
        {
            smp = tmp->next->next;
            tmp->next = NULL;
            tmp->next = smp;
            continue;
        }
        tmp = tmp->next;
    }
}
  • 删除链表中指定位置的节点
void Erase(pList *pplist, pList pos)
{
    pList tmp = NULL;
    pList smp = NULL;
    tmp = (*pplist);
    if (tmp->next == NULL)
    {
        printf("空链表\n");
        return;
    }
    else if (tmp->next->next == NULL && pos == tmp->next)
    {
        free(tmp->next);
        tmp->next = NULL;
    }
    else
    {
        smp = pos->next;
        int i = pos->data;
        pos->data = smp->data;
        smp->data = i;
        pos->next = pos->next->next;
    }
}
  • 把链表从尾到头打印
void PrintTailToHead(pList *pplist)
{
    //时间复杂度较高

    pList tmp = NULL;
    pList end = NULL;//标兵
    tmp = (*pplist);
    end = (*pplist);
    /*while (end->next != NULL)
    {
    end = end->next;
    }
    while (tmp->next != NULL)
    {
    if (tmp->next == end)
    {
    printf("%d ", end->data);
    end = tmp;
    tmp = (*pplist);
    continue;
    }
    tmp = tmp->next;
    }*/

    //空间复杂度较高
    /*DataType arr[Max] = { 0 };
    int i = 0;
    while (tmp->next != NULL)
    {
        arr[i] = tmp->data;
        tmp = tmp->next;
        i++;
    }
    arr[i] = tmp->data;
    for (; i > 0; i--)
    {
        printf("%d  ", arr[i]);
    }*/

    //递归的方式
    if (tmp->next == NULL)
    {
        return;
    }
    PrintTailToHead(&(tmp->next));
    printf("%d ", tmp->next->data);
}
  • 链表的逆置。利用两个指针,不懂得画画图
void ReverseList(pList* pplist)  //逆置(反转0)
{
    pList q = (*pplist)->next;
    pList p = q->next;
    while (p)  //当p指向NULL时,表明倒置完成,退出循环
    {
        q->next = p->next;
        p->next = (*pplist)->next;
        (*pplist)->next = NULL;
        (*pplist)->next = p;
        p = q->next;
    }
}
  • 链表的冒泡排序 (只交换数据,不交换节点)。
void BubbleSort(pList * pplist)  //交换数据没写交换节点
{
    pList q = NULL;
    pList p = NULL;
    for (int i = 0; i < Size(*pplist); i++) //Size 函数是求链表的长度
    {
        pList q = (*pplist)->next;
        pList p = q->next;
        for (int j = 0; j < Size(*pplist) - i - 1; j++)
        {
            while (p)
            {
                if (q->data < p->data)
                {
                    DataType tmp = q->data;
                    q->data = p->data;
                    p->data = tmp;
                }
                p = p->next;
                q = q->next;
            }
        }
    }
}
  • 求链表的中间节点(定义快慢指针,快指针一次走两个节点,慢指针一次走一个节点,当快指针走到链表的结尾时,慢指针刚好走到链表中间)
int FindMidNode(pList plist)
{
    pList fast = NULL;
    pList slow = NULL;
    fast = plist->next;
    slow = fast;
    while (fast)
    {
        if (fast->next)
        {
            fast = fast->next->next;
        }
        else
        {
            break;
        }
        slow = slow->next;
    }
    return slow->data;
}
  • 查找单链表的倒数第k个节点,要求只能遍历一次链表。(定义两个指针指向头节点,先让一个指针走k个节点,然后两个同时往后走,快指针到链表的结尾时,慢指针刚好就是链表倒数第k个节点)
int DelLastKNode(pList plist, int k) 
{
    pList p = NULL;
    pList q = NULL;
    q = plist->next;
    p = q;
    for (int i = 1; i < k; i++)
    {
        q = q->next;
    }
    while (q->next)
    {
        p = p->next;
        q = q->next;
    }
    return p->data;
}
  • 单链表实现约瑟夫环(约瑟夫环相当于链表的尾节点指向链表中的某一节点,从而形成环。)
int pLinkNodeJosephCycle(pList * pplist, int num)
{
    pList tmp = NULL;
    pList p = NULL;
    p = (*pplist)->next;
    tmp = (*pplist);
    while (tmp->next)
    {
        tmp = tmp->next;
    }
    tmp->next = (*pplist)->next;
    while (p != p->next)
    {
        for (int i = 1; i < num - 1; i++)
        {
            p = p->next;
        }
        p->next = p->next->next;
        p = p->next;
    }
    return p->data;
}

-删除一个无头单链表的非尾节点(要删除指定位置元素,那么就把指定位置元素和下一位置元素交换位置,然后删除下一个节点即可)

void EraseNotTail(pList pos) //删除一个无头单链表的非尾节点
{
    pList tmp = pos->next;
    pList smp = NULL;
    smp = pos->data;
    pos->data = tmp->data;
    tmp->data = smp;
    pos->next = tmp->next;
}
  • 在无头单链表的一个节点前插入一个节点(在这个节点后面插入一个新的节点,然后交换这个节点和新的节点的位置就可以了)
void InsertNode(pList pos)  //在无头单链表的一个节点前插入一个节点
{
    pList tmp = pos;
    pList smp = NULL;
    pList rmp = NULL;
    smp = (pList)malloc(sizeof(List));
    smp->data = 6; 
    smp->next = NULL;
    while (tmp->next)
    {
        tmp = tmp->next;
    }
    tmp->next = smp;

    int t = pos->data;
    pos->data = smp->data;

    pos = pos->next;
    while (pos)
    {
        int m = pos->data;
        pos->data = t;
        t = m;
        pos = pos->next;
    }
}
  • 列表内容
pList pLinkNodeMerge(pList plist1, pList plist2)  //合并两个(有序链表!!!), //合并后依然有序。(申请一个新链表,然后两个链表从一个元素开始比较,小的存储,并  //且指针向后移动,大的不动,再次比较。等到一个链表到尾的时候,就把另一个链表的直  //接插到新链表的后面即可。)
{
    pList pOneNode = plist1->next;
    pList pTwoNode = plist2->next;
    pList pRemain = plist1->next;
    pList pResult = NULL;
    pList pNode = NULL;
    InitLinkList(&pResult);

    while (pOneNode != NULL && pTwoNode != NULL)
    {
        if (pOneNode->data < pTwoNode->data)
        {
            PushBack(&pResult, pOneNode->data);
            pOneNode = pOneNode->next;
        }
        else
        {
            PushBack(&pResult, pTwoNode->data);
            pTwoNode = pTwoNode->next;
        }
    }

    if (pOneNode == NULL)
    {
        pRemain = pTwoNode;
    }
    else
    {
        pRemain = pOneNode;
    }

    for (pNode = pRemain; pNode != NULL; pNode = pNode->next)
    {
        PushBack(&pResult, pNode->data);
    }
    return pResult;
}
  • 求两个有序单链表交集
void UnionSet(pList* plist1, pList* plist2)  //求两个有序单链表交集(差集)
{
    pList tmp = NULL;
    pList smp = NULL;
    pList amp = NULL;
    amp = (*plist1);
    smp = (*plist2)->next;
    tmp = (*plist1)->next;
    while (tmp)
    {
        smp = (*plist2)->next;
        while (smp)
        {
            if (tmp->data == smp->data)
            {
                amp->next->data = smp->data;
                amp = amp->next;
                break;
            }
            smp = smp->next;
        }
        tmp = tmp->next;
    }
    amp->next = NULL;
}
  • 判断单链表是否带环?若带环,求环的长度?求环的入口点?(判断带环,我这里用的这种方法。定义两个指针,一个每次走两步,一个每次走一步,等到两个指针相等的时候,单链表有环。然后顺着这个交点走一圈就是环的长度。这个交点就是环的入口点)
pList CheckCycleandLength(pList plist)
{
    int count = 1;
    pList Head = NULL;
    pList Slow = NULL;
    pList tmp = NULL;
    Head = plist;
    Slow = plist;
    while (Head && Slow->next)
    {
        Head = Head->next->next;
        Slow = Slow->next;
        if (Head == Slow)
        {
            printf("链表带环\n");
            break;
        }
    }

    tmp = Head->next;
    while (tmp != Head)
    {
        tmp = tmp->next;
        count++;
    }
    printf("链表长度:%d\n", count);

    if (Head == Slow)
    {
        printf("环的起始位置:");
        return Slow->next;
    }
}
  • -
void CheckNoCross(pList list1, pList list2)  //判断两个链表是否相交。(假设链表不带环)(将一个链表的尾指向另一个链表的头,如果能构成一个环,那么两链表是相交的。)
{
    pList plist1 = NULL;
    pList plist2 = NULL;

    plist1 = list1;
    plist2 = list2;

    while (plist1->next)
    {
        plist1 = plist1->next;
    }
    while (plist2->next)
    {
        plist2 = plist2->next;
    }
    if (plist1 == plist2)
    {
        printf("两链表相交\n");
    }
    else
    {
        printf("两链表不相交\n");
    }
}
  • 不带环链表相交后的交点(求两个链表的长度,两个长度相减,假设为k,那么先让长链表走k步,然后两个链表一起走,走到相等的位置了就是交点。)
void PointList(pList plist1, pList plist2)  //不带环链表相交的交点。(假设链表不带环)
{
    int count1 = Size(plist1);
    int count2 = Size(plist2);
    int k = count1 - count2;

    if (k > 0)
    {
        while (k--)
        {
            plist1 = plist1->next;
        }
        while (1)
        {
            plist1 = plist1->next;
            plist2 = plist2->next;
            if (plist1 == plist2)
            {
                printf("交点为:%d\n", plist1->data);
                break;
            }
        }
    }
    if (k < 0)
    {
        while (k++)
        {
            plist2 = plist2->next;
        }
        while (1)
        {
            plist1 = plist1->next;
            plist2 = plist2->next;
            if (plist1 == plist2)
            {
                printf("交点为:%d\n", plist1->data);
                break;
            }
        }
    }
    if (k == 0)
    {
        while (1)
        {
            plist1 = plist1->next;
            plist2 = plist2->next;
            if (plist1 == plist2)
            {
                printf("交点为:%d\n", plist1->data);
                break;
            }
        }
    }
}
  • 判断带环链表是否相交,并且求两链表的交点。(带环链表的相交有两种情况,1、环外相交。2、环内相交。先求两个链表的环的入口点,如果两个链表环的入口点相等,那么两链表相交,并且交点在环的上面的某一位置;那么接下来就把环的入口点的位置记下来,就可以求出交点。如果两个链表环的入口点不相等,那么两链表可能不相交,或者可能在环内部相交;让其中一个链表从环开始往后走,如果找到另外一个链表的环的入口点,那么说明两链表相交,否则两链表不相交。)
pList CheckHaveCross(pList list1, pList list2)  
{
    pList plist1 = NULL;
    pList plist2 = NULL;
    pList plist3 = NULL;
    pList plist4 = NULL;
    pList loop1 = NULL;
    pList loop2 = NULL;
    pList Cur1 = NULL;
    pList Cur2 = NULL;

    plist1 = list1;
    plist2 = list1;
    plist3 = list2;
    plist4 = list2;
    Cur1 = list1;
    Cur2 = list2;

    while (plist1 && plist2->next)  //求链表1的环的起始点
    {
        plist1 = plist1->next->next;
        plist2 = plist2->next;
        if (plist1 == plist2)
        {
            loop1 = plist1;
            break;
        }

    }

    while (plist3 && plist4->next)  //求链表2的环的起始点
    {
        plist3 = plist3->next->next;
        plist4 = plist4->next;
        if (plist3 == plist4)
        {
            loop2 = plist3;
            break;
        }
    }

    if (loop1 == loop2) //两链表相交,并且交点在环上面
    {
        int n = 0;
        while (Cur1 != loop1)
        {
            n++;
            Cur1 = Cur1->next;
        }
        while (Cur2 != loop2)
        {
            n--;
            Cur2 = Cur2->next;
        }
        Cur1 = n > 0 ? list1 : list2;
        Cur2 = Cur1 == list1 ? list2 : list1;
        n = abs(n);
        while (n != 0)
        {
            n--;
            Cur1 = Cur1->next;
        }
        while (Cur1 != Cur2)
        {
            Cur1 = Cur1->next;
            Cur2 = Cur2->next;
        }
        return Cur1;
    }
    else   //两种情况,两链表不相交;两链表在环内相交
    {
        Cur1 = loop1->next;
        while (Cur1 != loop1)
        {
            if (Cur1 == loop2)
            {
                return loop1;
            }
            Cur1 = Cur1->next;
        }
        return NULL;
    }
}
  • 关于复杂链表的复制。(创建复杂链表的节点和打印复杂链表我就不说了。我来说说关于复杂链表的复制。)
    1、第一步:根据原始链表的每个结点N创建对应的N’,然后将N‘通过next接到N的后面;
    2、 第二步:设置复制出来的结点的random。假设原始链表上的N的random指向结点S,那么其对应复制出来的N’是N->next指向的结点,同样S’也是结点S->next指向的结点。
    3、第三步:把长链表拆分成两个链表,把奇数位置的结点用next连接起来的就是原始链表,把偶数位置的结点通过next连接起来的就是复制链表。
ComplexNode * BuyComplexNode(DataType x)  //创建一个复杂链表的结点
{
    ComplexNode *cnode = (ComplexNode *)malloc(sizeof(ComplexNode));
    if (cnode == NULL)//创建失败
    {
        perror("BuyComplexNode()::malloc");
        return NULL;
    }
    //创建成功
    cnode->_data = x;
    cnode->_next = NULL;
    cnode->_random = NULL;
    return cnode;
}


void Display(const ComplexNode * cplist)   //打印复杂的单链表
{
    ComplexNode *pnode = cplist;
    while (pnode)
    {
        printf("%d::%d -->", pnode->_data, pnode->_random->_data);
        pnode = pnode->_next;
    }
    printf("over\n");
}

ComplexNode * CopyComplexNode(ComplexNode * cplist)  //复杂链表的复制
{
    ComplexNode * pold = NULL;
    ComplexNode * pnew = NULL;
    ComplexNode * newlist = NULL;//指向新的复杂链表的头结点的指针
    pold = cplist;

    //创建一条新的复杂链表
    while (pold != NULL)
    {
        ComplexNode * new_node = BuyComplexNode(pold->_data);

        if (newlist == NULL)//当新的复杂链表中没有结点时
        {
            newlist = new_node;
        }
        else    //当新的复杂链表有结点时
        {
            ComplexNode * node = newlist;
            while (node->_next != NULL)//找到最后一个结点
            {
                node = node->_next;
            }
            node->_next = new_node;//插入新的结点
        }
        pold = pold->_next;
    }//创建新的复杂链表结束

    //合并两条复杂链表
    pold = cplist;
    pnew = newlist;
    while (pold)
    {
        ComplexNode * curold = NULL;
        ComplexNode * curnew = NULL;
        curold = pold->_next;
        curnew = pnew->_next;
        if (pold->_next == NULL)
        {
            pold->_next = pnew;
            pold = curold;
            pnew = curnew;
            break;
        }
        pold->_next = pnew;
        pnew->_next = curold;
        pold = curold;
        pnew = curnew;
    }//合并两条复杂链表结束

    //让新创建的那条复杂链表上的所有结点的random指针指向相应的结点
    pold = cplist;
    pnew = newlist;
    while (pnew)
    {
        pnew->_random = pold->_random->_next;
        pold = pnew->_next;
        if (pold == NULL)//这是pnew的_next指针已经指向空
        {
            break;
        }
        pnew = pold->_next;
    }//结束

    //分离合并后的复杂链表
    pold = cplist;
    pnew = newlist;
    while (pold)
    {
        ComplexNode * curold = NULL;
        ComplexNode * curnew = NULL;
        if (pnew->_next == NULL)//已经分离完成
        {
            pold->_next = NULL;
            pnew->_next = NULL;
            break;
        }
        curold = pold->_next->_next;
        curnew = pnew->_next->_next;
        pold->_next = curold;
        pnew->_next = curnew;
        pold = curold;
        pnew = curnew;
    }//分离合并的复杂链表结束
    return newlist;
}
测试代码我就不给出了,都是一些很简单的代码。

这是我关于链表的一些认识和一些见解,由于能力有限,解释的也有点牵强,如有问题,还望一同探讨

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值