周练--C

目录

一.力扣27-移除元素

1.题目

2.思考 

3.代码

3.代码2

二.力扣88-合并两个有序数组

1.题目

2.想法:

3.代码 

三.剑指offer交换奇偶数的位置

1.题目

2. 分析

3.代码 

 四.剑指offer56题

1.tip:

2.代码: 

五.剑指offer---计算一个整数在计算机存储的二进制位中1的个数

代码1

代码2

六.力扣-消失的数字 

思路

七.循环右移

八.力扣206-反转链表

1.题目

2. 代码

1--头插

3.递归---整个链表反转

 3.1递归--前n个结点反转

3.2反转部分链表—递归92

 3.2.1-循环头插--反转部分链表92

九.力扣876-链表的中间节点 (要求遍历一次)

1.题目 

2.图解 

十.链表中第K个结点

tips:

代码

十一.分割链表

1.题目

2.图解​编辑

 3.代码

十二.回文链表

1.tips

2.代码

十三.160相交链表

十四.141.2环形链表

十五.快慢指针


一.力扣27-移除元素

1.题目

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-element
 

2.思考 

1e6dae55b3dc4f7ab6b7c32ccb41cf89.png这是思路一

思路二:以空间换时间:不是val的数据放在新数组里,再把新数组的只拷贝过去(不符合题意);空间复杂度为O(n)

思路三用双指针:此时时间复杂度为O(N),空间复杂度为O(1)

1.src位置不是val就放到dst位置然后src++,dst++;

2.src位置是val,src++;

3.在src往后遍历过程中,在2的前提下如果src!=val,就让src所指的元素移到dst所指向的位置d34dd4c2091d48dcabdf433cc0f5214f.jpeg

3.代码

int removeElement(int* nums, int numsSize, int val)
{
    int src =0;
    int dst=0;
    while(src<numsSize)
    {
        if(nums[src]!=val)
        {
            nums[dst++]=nums[src++];
        }
        else
        {
            ++src;
        }
    }
    return dst;
}

3.代码2

203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

9c9840c1e0ec3aa22a8ec78210cfdd47.jpeg

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode*prev=NULL;
    struct ListNode*cur=head;
    while(cur)
    {
        //1.是头部节点
        //2.删除中间元素
        if(cur->val==val)
        {
            if(cur==head)
            {
                head=cur->next;//如果直接先free,会把这个位置的值和next变成随机值
                free(cur);
                cur=head;
            } 
            else
             {
            
             prev->next=cur->next;
             free(cur);
             cur=prev->next;
        
       
             }
        }
        else
        {
            prev=cur;
            cur=cur->next;
        
        }
    }
    return head;
}

二.力扣88-合并两个有序数组

1.题目

 2fd5a2c98cff451db53b7c59c8fa95e7.png

a9a5793f7fe3445d96fe89dfb9c33690.png

2.想法:

nums1和nums2都从后往前走,取大的从后往前放(演示过程如下视频)如果从前往后覆盖,很有可能将num1前面的元素弄没。 也可以从后往前覆盖而后排序,但是效率会变低。。 会出现下面情况 6e7cfcdf2ec548f897a9951d4e5cbad7.jpeg

时间复杂度为O(m+n),空间复杂度为O(1)

15-03-16

3.代码 

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
    int end1=m-1;
    int end2=n-1;
    int end=m+n-1;
    while(end1>=0&& end2>=0)
    {
        if(nums1[end1]>nums2[end2])
        {
            nums1[end]=nums1[end1];
            --end;
            --end1;
        }
        else
        {
            nums1[end]=nums2[end2];
            --end;
            --end2;
             
        }
    }
    //如果是nums1没完不需要处理,因为就是归于nums1里面
    while(end2>=0)
    {
        nums1[end]=nums2[end2];
            --end;
            --end2;
             

    }


}

三.剑指offer交换奇偶数的位置

1.题目

b61c83986f394e5b9838aff3c53bcab0.png

2. 分析

如果left为偶数,right为奇数,则交换两数的位置(其中有3处易错点已用注释标出)

3.代码 

#include<stdio.h>
void swap(int* arr, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		while ((left < right) && (arr[left] % 2 == 1))//如果arr数组中全是奇数,虽然不会报错但是你会越界访问!!!
		{
			left++;
		}
		while ((left<right) && (arr[right] % 2 == 0))//全是偶数也会越界,就没有必要遍历了
		{
			right--;
		}
		if (left < right)//如果不加if你会多交换一次,在有些情况下,会让本来交换好的奇数与偶数再交换一次,大错特错
		{
			int temp = arr[left];
			arr[left] = arr[right];
			arr[right] = temp;
		}
	}
}
int print(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 6,8,1,9,2,3,5,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	swap(arr, sz);
	print(arr, sz);
	return 0;
}

 四.剑指offer56题

一组数据中只有一个数字出现了一次,其他所有数字都是成对出现的,请找出这个数字采用位运算(同0异1)

1.tip:

 ^ 小知识复习:

0与任何一个数字异或的结果都等于这个数;两个相同的数字异或的结果为0;

eg: 1 2 3 1 2 五个数字进行异或,结果为 3;

2.代码: 

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4 };
	int ret = 0;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		ret ^= arr[i];
	}
	
	return 0;
}

五.剑指offer---计算一个整数在计算机存储的二进制位中1的个数

*这道题需要注意负整数哦

代码1

(这样子写在当年的谷歌面试中并未得到欣赏,但是我可能还想不出来这个"......")

#include<stdio.h>

int main()
{
	int a = -1;//-1在计算机中的补码是32个1哦
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		
		if ((1 & (a >> i)) == 1)
			count++;
		
	
	}
	printf("%d", count);

	return 0;
}

代码2

分析:以15举例(&是同1异0)

numnum-1

num&(num-1)  结果

赋值给下一个num

num中1的个数
1111111011104
1110110111003
1100101010002
1000011100001
#include<stdio.h>
int main()
{
	int a = -1;
	int count = 0;
	while (a)
	{
		a = a & (a - 1);
		count++;
	}
	printf("%d", count);
	return 0;
}

3.或者就是写一个函数,参数中改为(unsigned int a)

六.力扣-消失的数字 

思路

1.给定一个x的值为0,让他与[0,n]中所有的数字异或,再和数组中的每个值进行异或,最后所得到的值就是消失的数字;(回到题目四)//注意:[0,n]是n+1个数字哦

2.(0+...n)-(arr[0]+...arr[n-1])   时间复杂度O(n),空间复杂度O(1);

3.。。。 

七.循环右移

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

进阶:

  • 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

1.暴力求解---循环k次---O(n*k)(可以看看左旋数组-代码整合那个博客,思路是一样的)

2.额外开辟空间

3.左逆序右逆序全部逆序----可以做到以O(1)的空间复杂度 注意栈溢出的那点哦

void rotate(int* nums, int numsSize, int k)
{
    if(k>numsSize)//没有这步的话会栈溢出
    {
        k=k%numsSize;
    }
    Reverse(nums,0,numsSize-k-1);
    Reverse(nums,numsSize-k,numsSize-1);
    Reverse(nums,0,numsSize-1);
}
void Reverse(int*nums,int left,int right)
{
    while(left<right)
    {
        int temp=nums[left];
        nums[left]=nums[right];
        nums[right]=temp;
        ++left;
        --right;

    }
}

八.力扣206-反转链表

1.题目

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

0bd15b2b3174818fb8cbe3aa5c5f005e.jpeg

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

0f23dd6c3789746423e7f8fb1baf1eb4.jpeg

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]
提示:
  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000
  • 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

2. 代码

1--头插

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*cur=head;
    struct ListNode*newNode=NULL;
    while(cur)
    {
        struct ListNode*next=cur->next;
        //头插
        cur->next=newNode;
        newNode=cur;
        //迭代
        cur=next;
    }
    return newNode;
}

2-迭代

//n1--prev,n2--cur,n3--next便于迭代,不然n1,n2之间的链表断开,怎末走到下一个
//反转的终止条件是n2为空
struct ListNode* reverseList(struct ListNode* head)
{
    
  if(head==NULL)//如果没有这步,下面代码中n2=head,n3=head->next就会出现空指针报错的情况
    {
        return NULL;
    }
    struct ListNode*n1,*n2,*n3;
    n1=NULL;
    n2=head;
    n3=head->next;
    while(n2)
    {
        //核心逻辑-反转
        n2->next=n1;
        //迭代
        n1=n2;
        n2=n3;
        if(n3)//如果没有这步会出现空指针报错
            n3=n3->next;

    }
    return n1;
}

3.递归---整个链表反转

820c908bbe46458294e0dd80649a3c5b.png

1.结束条件:只有一个结点或者没有结点;

2.处理第一个节点与子链表翻转后的头结点

3.返回最终的节点

23a2001175f144d592f0285af9ceff8b.png

 3.1递归--前n个结点反转

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* successor = NULL; // 后驱节点
// 反转以 head 为起点的 n 个节点
struct ListNode*reverseN(struct ListNode* head, int n) {
    if (n == 1) 
    { 
        // 记录第 n + 1 个节点
        successor = head->next;
        return head;
    }
    // 以 head.next 为起点,需要反转前 n - 1 个节点
    struct ListNode* last = reverseN(head->next, n - 1);
    head->next->next = head;
    head->next = successor;
    return last;
}    

3.2反转部分链表—递归92

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

0a9c2caf222b911bb90e597326672ac7.jpeg

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* successor = NULL; // 后驱节点
// 反转以 head 为起点的 n 个节点
struct ListNode*reverseN(struct ListNode* head, int n) {
    if (n == 1) 
    { 
        // 记录第 n + 1 个节点
        successor = head->next;
        return head;
    }
    // 以 head.next 为起点,需要反转前 n - 1 个节点
    struct ListNode* last = reverseN(head->next, n - 1);
    head->next->next = head;
    head->next = successor;
    return last;
}    
//
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) 
{
    if (m == 1)
    {
        return reverseN(head, n);
    }
    head->next = reverseBetween(head->next, m - 1, n - 1);
    return head;
}/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* successor = NULL; // 后驱节点
// 反转以 head 为起点的 n 个节点
struct ListNode*reverseN(struct ListNode* head, int n) {
    if (n == 1) 
    { 
        // 记录第 n + 1 个节点
        successor = head->next;
        return head;
    }
    // 以 head.next 为起点,需要反转前 n - 1 个节点
    struct ListNode* last = reverseN(head->next, n - 1);
    head->next->next = head;
    head->next = successor;
    return last;
}    
//
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) 
{
    if (m == 1)
    {
        return reverseN(head, n);
    }
    head->next = reverseBetween(head->next, m - 1, n - 1);//这步会最终回到m==1那里
    return head;
}

来源:力扣

 3.2.1-循环头插--反转部分链表92

f87dc94ef7174655865651a054b9b7df.png

struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
    struct ListNode*dummy=(struct ListNode*)malloc(sizeof(struct ListNode));//如果left等于一我们还得找头节点,所以此时我们创建一个头部哨兵节点,避免这种情况
    dummy->next=head;
    struct ListNode*pre=dummy;
    for(int i=0;i<left-1;i++)
    {
        pre=pre->next;//先走到left节点之前的一个
    }
    struct ListNode*cur=pre->next;
    for(int i=0;i<right-left;i++)//需要反转的结点依次头插到cur之前
    {
        struct ListNode*next=cur->next;
        cur->next=next->next;
       
        next->next=pre->next;
        pre->next=next;//帮你试过了这三个顺序不能变,否则会超出时间限制
    }
    return dummy->next;//感觉好像还需要free;???


}

九.力扣876-链表的中间节点 (要求遍历一次)

1.题目 

给定一个头结点为 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

2.图解 

 采用双指针-分两种情况

ecb04667804d41d3acbc08bed9b30677.png

struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

十.链表中第K个结点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

tips:

fast先走k步,而后fast和slow共同走

考虑如果k大于数组长度,会造成空指针类型的报错,所以

代码

struct ListNode* getKthFromEnd(struct ListNode* head, int k)
{
    struct ListNode*fast,*slow;
    fast=slow=head;
    //while(--k)//进去k-1次
     while(k--)//进去k次
     {
        //k大于链表的长度
        if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
     }
    while(fast)
    {
       
        
        fast =fast->next;
        slow=slow->next;
    }
    return slow;
}

十一.分割链表

1.题目

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你不需要 保留 每个分区中各节点的初始相对位置。
链接:https://leetcode.cn/problems/partition-list-lcci

2.图解991c92af9a0041889bbc1b350d6f5613.png

 3.代码

//注意头尾边界
struct ListNode* partition(struct ListNode* head, int x)
{
    struct ListNode*lesshead,*lesstail,*greaterhead,*greatertail;
   //开辟一个头结点方便后续尾插
   lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
   lesstail->next=NULL;
   greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
   greatertail->next=NULL;
   struct ListNode*cur=head;
   while(cur)
   {                                                 
       if(cur->val<x)
       {
           lesstail->next=cur;
           lesstail=cur;
       }
       else
       {
           greatertail->next=cur;
           greatertail=cur;
       }
        cur=cur->next;
        
   }
   lesstail->next=greaterhead->next; 
   struct ListNode*newNode=lesshead->next;
   greatertail->next=NULL; 
   free(lesshead);
   free(greaterhead);
   return newNode;
   
}

十二.回文链表

1.tips

1.双指针遍历

2.先找链表中部节点,后半部分链表翻转,判断前面链表与后面翻转后的链表中的元素(奇数或偶数个元素都没关系,也没必要去取消连接);

2.代码

//快慢指针找中值;翻转后半部分的链表;前部分后部分进行比较
struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*cur=head;
    struct ListNode*newNode=NULL;
    while(cur)
    {
        struct ListNode*next=cur->next;
        //头插
        cur->next=newNode;
        newNode=cur;
        //迭代
        cur=next;
    }
    return newNode;
}
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}
bool isPalindrome(struct ListNode* head)
{
    struct ListNode*mid=middleNode(head);
    struct ListNode*rhead=reverseList(mid);
    struct ListNode*curhead=head;
    struct ListNode*currhead=rhead;
    while(curhead&&currhead)
    {
        if(curhead->val!=currhead->val)
        {
            return false;
        }
        else//上一个相等了就继续去判断下个是否相等
        {
            
            curhead=curhead->next;
            currhead=currhead->next;
        }
    }
    return true;



}//快慢指针找中值;翻转后半部分的链表;前部分后部分进行比较
struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*cur=head;
    struct ListNode*newNode=NULL;
    while(cur)
    {
        struct ListNode*next=cur->next;
        //头插
        cur->next=newNode;
        newNode=cur;
        //迭代
        cur=next;
    }
    return newNode;
}
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}
bool isPalindrome(struct ListNode* head)
{
    struct ListNode*mid=middleNode(head);
    struct ListNode*rhead=reverseList(mid);
    struct ListNode*curhead=head;
    struct ListNode*currhead=rhead;
    while(curhead&&currhead)
    {
        if(curhead->val!=currhead->val)
        {
            return false;
        }
        else//上一个相等了就继续去判断下个是否相等
        {
            
            curhead=curhead->next;
            currhead=currhead->next;
        }
    }
    return true;



}

十三.160相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/intersection-of-two-linked-lists 

时间复杂度O(n)

尾节点相同就是相交

找交点:长的链表先走(长度差步),然后俩同时走,第一个相同的就是所求。

十四.141.2环形链表

fast一次走两步,slow一次走一步,不带环fast会为空,带环,则两者相遇。

bool hasCycle(struct ListNode *head) {
    struct ListNode*fast=head,*slow=head;
    while(fast&&fast->next)//如果链表中的元素是奇数个并且不是环状
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }
    return false;
    
    
}

1.双指针fast语slow,fast一次走两步,slow一次走一步,fast与slow一定在环内相遇,如果fast一次走的不是2步(n>2),则不一定。

2.环的入口如何找?

一个指针从相遇点开始走,另一个从链表头开始走,他们会在环的入口点相遇。

L=N*C-x,C指的是环的长度,x代表从入环点到相遇位置的距离,L表示从链表头到入环点之间的距离,N表示再相遇前,快指针在环内走的圈数。

L=(N-1)*C+C-x    (N-1)*C表示他从meetnode又走到meetnode

9c2a46ccbcd945f380d9e1879eb8ec9c.png

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode*fast=head,*slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            //相遇
            struct ListNode*meet=slow;
            //公式证明的
            while(meet!=head)
            {
                meet=meet->next;
                head=head->next;
            }
            return meet;
        }

    }
    return NULL;
}

十五.快慢指针

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

b3371ebcc45d51519c8e3a7635a82665.jpeg

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

bec85c42d8a64a0e958c41a5b1bd6aa9.png

struct ListNode* removeNthFromEnd(struct ListNode* head, int n)
{
    struct ListNode*newNode=(struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode*fast=head;
    struct ListNode*slow=newNode;
    newNode->next=head;
    for(int i=0;i<n;i++)
    {
        fast=fast->next;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    struct ListNode*temp=slow->next;
    slow->next=temp->next;
    free(temp);
    slow=newNode->next;
    free(newNode);
    return slow;

}struct ListNode* removeNthFromEnd(struct ListNode* head, int n)
{
    struct ListNode*newNode=(struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode*fast=head;
    struct ListNode*slow=newNode;
    newNode->next=head;
    for(int i=0;i<n;i++)
    {
        fast=fast->next;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    struct ListNode*temp=slow->next;
    slow->next=temp->next;
    free(temp);
    slow=newNode->next;
    free(newNode);
    return slow;

}

  • 20
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sqyaa.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值