剑指Offer刷题记录 - part three(python版本)

15. 用两个栈实现队列

题目要求

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

解题思路

  1. 辅助栈解法(类似汉诺塔);
  2. 把第二个栈做倒序。

代码

# class CQueue:
##  汉诺塔解法
#     def __init__(self):
#         self.stack1 = []
#         self.stack2 = []


#     def appendTail(self, value: int) -> None:
#         # stack1 to stack2
#         while self.stack1:
#             self.stack2.append(self.stack1.pop())
#         self.stack1.append(value)
#         # stack2 to stack1
#         while self.stack2:
#             self.stack1.append(self.stack2.pop())


#     def deleteHead(self) -> int:
#         if self.stack1 == []: return -1
#         return self.stack1.pop()

class CQueue:
# 倒序解法
    def __init__(self):
        self.stack1 = []
        self.stack2 = []


    def appendTail(self, value: int) -> None:
        # add stack1
        self.stack1.append(value)


    def deleteHead(self) -> int:
    # 法一
        if self.stack2: return self.stack2.pop()
        if self.stack1 == []: return -1
        
        # 倒序
        while self.stack1:
            self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

    def deleteHead(self) -> int:
    # 法二
        if not self.stack2:
            if not self.stack1:
                return -1
            else:
                while self.stack1:
                    self.stack2.append(self.stack1.pop())
                return self.stack2.pop()
        else:
            return self.stack2.pop()


# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

汉诺塔解法:
在这里插入图片描述

  • 时间复杂度: appendTail()函数为 O(n) ;deleteHead() 函数也是O(n)。
  • 空间复杂度: 均为 O(n) 。

倒序解法:
在这里插入图片描述
在这里插入图片描述

  • 时间复杂度: appendTail()函数为 O(1) ;deleteHead() 函数在 N次队首元素删除操作中总共需完成
    N个元素的倒序。
  • 空间复杂度 : 最差情况下,栈 A 和 B 共保存 N个元素。

16. 包含min函数的栈

题目要求

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)

解题思路

push和pop的时间复杂度均为O(1),但要实现min的时间复杂度也为O(1)就需要使用辅助栈B来保存数据栈A的最小值。这种方法的空间复杂度需要O(n),最坏的情况是保存所有值。

https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/solution/mian-shi-ti-30-bao-han-minhan-shu-de-zhan-fu-zhu-z/

https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/solution/jian-zhi-30minhan-shu-zhan-fu-zhu-zhan-f-9dzb/

根据leetcode大佬们提供的思路,我选取了三种方法实现该算法。第一种是使用math.min来寻找最小值,第二种是使用if来判断,第三种是残差法(目前这个方法看不懂,后续看懂了再来补充)

代码

import math
class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        self.min_stack = [math.inf]


    def push(self, x: int) -> None:
        self.stack.append(x)
        # self.min_stack.append(min(x, self.min_stack[-1]))
        if not self.min_stack or self.min_stack[-1] >= x:
            self.min_stack.append(x)


    def pop(self) -> None:
        # self.stack.pop()
        # self.min_stack.pop()
        if self.stack.pop() == self.min_stack[-1]:
            self.min_stack.pop()


    def top(self) -> int:
        return self.stack[-1]


    def min(self) -> int:
        return self.min_stack[-1]



# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

使用math.min来寻找最小值:
在这里插入图片描述

使用if来判断:
在这里插入图片描述
很明显,不调用math函数会提高运行速度。

17. 从头到尾打印链表

题目要求

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

解题思路

  1. 辅助栈:用一个列表来保存链表的数值,然后使用[::-1]倒序返回链表。
  • 时间复杂度: 入栈和出栈一共使用 O(n) 时间。
  • 空间复杂度: 辅助栈 result 和数组 res 共使用 O(n)的额外空间。
  1. 递归。时间复杂度: 遍历链表,递归 n 次。空间复杂度 : 系统递归需要使用 O(n) 的栈空间。

代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        # 辅助栈 40ms
        # result = []
        # while head:
        #     result.append(head.val)
        #     head = head.next
        # return result[::-1]

        # 递归法 108ms
        return self.reversePrint(head.next) + [head.val] if head else []

在这里插入图片描述
虽然两种方法的时间复杂度和空间复杂度是一样的。在具体的运行中,递归法的时间复杂度和空间复杂度会多很多。

https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/mian-shi-ti-06-cong-wei-dao-tou-da-yin-lian-biao-d/

18. 反转链表

题目要求

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

解题思路

  1. 迭代法。
  • 时间复杂度: O(n)
  • 空间复杂度: 由于没有开辟新的额外空间,因此空间复杂度为O(1)。
  1. 递归。
  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        # 迭代 24ms
        # pre, cur = None, head
        # while cur:
        #     tmp = cur.next
        #     cur.next = pre
        #     pre = cur
        #     cur = tmp
        # return pre

        # 递归 28ms
        def recur(cur, pre):
            if not cur: return pre
            res = recur(cur.next, cur)
            cur.next = pre
            return res
        return recur(head, None)

在这里插入图片描述
可以看出,递归方法虽然简单,但是会消耗大量的时间和占用空间。

https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/shi-pin-tu-jie-jian-zhi-offer-24-fan-zhu-oym7/

19. 复杂链表的复制

题目要求

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
在这里插入图片描述

解题思路

没咋看懂,代码是官网上大佬们的解答。第一种哈希表比较好懂。
https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/

代码

"""
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
"""
class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        # 哈希表
        # if not head: return None
        # dic = {}
        # cur = head
        # while cur:
        #     dic[cur] = Node(cur.val)
        #     cur = cur.next
        # cur = head
        # while cur:
        #     dic[cur].next = dic.get(cur.next)
        #     dic[cur].random = dic.get(cur.random)
        #     cur = cur.next
        # return dic[head]

        # 直接复制
        # return copy.deepcopy(head)

        # 拼接+拆分
        if not head: return None
        cur = head
        # 1. 复制各节点,并构建拼接链表
        while cur:
            temp = Node(cur.val)
            temp.next = cur.next
            cur.next = temp
            cur = temp.next
        # 2. 构建各新节点的 random 指向
        cur = head
        while cur:
            if cur.random:
                cur.next.random = cur.random.next
            cur = cur.next.next
         # 3. 拆分两链表
        cur = res = head.next
        pre = head
        while cur.next:
            pre.next = pre.next.next
            cur.next = cur.next.next
            pre = pre.next
            cur = cur.next
        pre.next = None # 单独处理原链表尾节点
        return res

在这里插入图片描述

20. 替换空格

题目要求

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

解题思路

乍一看,这是一道相当简单的题目,但是需要实现空间复杂度和时间复杂度都最小,那还是需要动脑子滴。

熟悉Python的小伙伴都知道,替换直接用replace就好啦,所以这也是思路之一。

第二种就是使用列表,因为字符串是不可改变对象,我们把字符串元素都变成列表,然后再转换回字符串就好啦。

第三种是先把空格分割开,用“%20”替换空格。

代码

class Solution:
    def replaceSpace(self, s: str) -> str:
        # 用列表替换
        # res = []
        # for c in s:
        #     if c == " ":
        #         res.append("%20")
        #     else:
        #         res.append(c)
        # return "".join(res)

        # 直接用replace
        # return s.replace(" ", "%20")

        # 先把空格分割,再把“%20”添加上
        s = s.split(" ")
        return "%20".join(s)

下面的结果是用replace方法得到的,其时间复杂度和空间复杂度都是O(n)。
在这里插入图片描述
下面是用列表得到的结果,很明显速度快了很多。其中,这种方法的时间复杂度和空间复杂度也是O(n)。
在这里插入图片描述
第三种方法的时间复杂度和空间复杂度都与上面两种一致。
在这里插入图片描述

21. 左旋转字符串

题目要求

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

解题思路

  1. 字符串切片。 我一开始想到的这个方法,代码是这样的:
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        if not s: return
        res = s[:n]
        s = s[n:] + res
        return s

然后去参考大神们的解法,一句话就把这个解决了。return s[n:] + s[:n] (大神不愧是大神!)

  1. 列表遍历拼接。 若面试不让使用切片函数,那就可以使用该方法。
    https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/
    在这里插入图片描述
    其中,列表遍历拼接的第二种方法是取余。我整理了一下大神们使用该方法的理由:
    遇到这类情况——如果n大于字符串长度,可以用取余来解决。就类似于数据结构的循环队列操作,n是线性增长的,通过取余可以让线性增长的数据在模内循环。

  2. 字符串遍历拼接。如果面试不让使用join(),可以采用该方法。
    与方法二类似,只是用字符串替代列表即可。同样的,该方法也可以用取余,原因法二类似。

代码

  1. 字符串切片的时间复杂度和空间复杂度均为O(n)
    时间复杂度:n为字符串s的长度,字符串切片函数为线性时间复杂度;
    空间复杂度:两个字符串切片的总长度为n。
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        # 字符串切片
        # 法一
        # if not s: return
        # res = s[:n]
        # s = s[n:] + res
        # return s
		
		# 法二
        return s[n:] + s[:n]

在这里插入图片描述
2.列表遍历拼接。时间复杂度和空间复杂度均为O(n)
时间复杂度:线性遍历字符串s并进行添加操作,使用线性时间;
空间复杂度:创建新的列表res开辟了n大小的额外空间。

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        # 列表遍历拼接
        # res = []
        # for i in range(n, len(s)):   # O(n)
        #     res.append(s[i])   # append() is O(1)
        # for i in range(n):
        #     res.append(s[i])   # O(1)
        # return "".join(res)   #O(n)

        res = []
        for i in range(n, n + len(s)):
            res.append(s[i % len(s)])
        return "".join(res)

在这里插入图片描述

  1. 字符串遍历拼接。
    时间复杂度O(n):和列表遍历拼接类似,线性遍历字符串s并添加操作。
    空间复杂度O(n):在字符串循环遍历过程中,内存会被回收,因此内存中至少同时存在长度n和n-1的两个字符串,所以至少使用O(n)的额外空间。
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
       
        # join不可用,可以使用字符串遍历拼接
        # res = ""
        # for i in range(n, len(s)):
        #     res += s[i]
        # for i in range(n):
        #     res += s[i]
        # return res

        res = ""
        for i in range(n, n + len(s)):
            res += s[i % len(s)]
        return res

在这里插入图片描述
以上三种方法的时间复杂度都是O(n),那为什么通过样例的时间和内存不一样呢?

K神的解释是:复杂度只是代表了随着输入数据的增长时的算法时间的增长,但是因为上面三种方法操作不一样,有的是用了for有的使用了取余,因此相同数据下的效率是有优劣的。

22. 数组中重复的数字

题目要求

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

限制:2 <= n <= 100000

解题思路

这道题有三种方法:
第一种,先排序然后遍历找到重复的数字,看起来思路简单,但是执行起来挺复杂的。时间复杂度是O(nlogn)。
第二种,哈希表了解哈希表 这篇文章用很生动的对话把哈希表讲解了一遍。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

第三种,原地交换。可以简单的理解为:①如果发现这个坑里的萝卜不是这个坑应该有的萝卜,就看看你是哪家的萝卜,然后把你送到你该去的地方,再把你家里现在的那个萝卜拿回家。②拿回家之后,再看看拿回来的萝卜是不是属于哪家的,再去找对应的家进行交换。③把上面的过程重复,直到把这个萝卜送回家时,发现这个家里面已经有萝卜了,出现重复了,这个萝卜就是多出来的。

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

代码

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        # 哈希表
        dic = set()
        for num in nums:
            if num in dic: return num
            dic.add(num)
        return -1

        # 原地交换
        for i in range(len(nums)):
            while nums[i] != i: #如果遇到下标i与nums[i]不一样,那么就要把这个nums[i]换到它应该去的下标下面
                temp = num[i]  # 用temp变量保存这个nums[i]
                if nums[temp] == temp:  # 如果那么下标下面已经被占了,那么就找到了重复,结束就好了!
                    return temp
                else:
                    nums[temp], nums[i] = nums[i], nums[temp]

哈希表
在这里插入图片描述
原地交换
在这里插入图片描述
疑问:看到上面两种解法明明是原地交换的空间复杂度比较低,那为什么内存消耗是一样的呢?

笔者在X乎上找到了答案。https://www.zhihu.com/question/380427506/answer/1089006544
在这里插入图片描述在这里插入图片描述

23. 最大子序和

题目要求

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

提示:

1 <= nums.length <= 3 * 104
-105 <= nums[i] <= 105

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

解题思路

这道题可以有三种解法,暴力法、动态规划和题目所提示的分治法。

  1. 暴力法思路可以参考链接,其时间复杂度是O(n2)。
  2. 动态规划思路就是找到当前指针的最大子序和,可能保留之前的数,也可以抛弃之前的数,取决于它是否“拖累”当前指针的最大子序和。
    时间复杂度:O(n),仅遍历一遍数组。
    空间复杂度:O(1),没有使用其他额外空间。
  3. 分治法。参考链接1参考链接2
    分治法使用的是递归的形式,把一个数组分成左右子数组,把它分到已经不可再分为止。然后通过比较左右两边数组的最大子序和。不仅如此,还需要对比把两边子数组合起来的最大数值,即查看中间线是否把最大子序分开,进行比较。
    最后把左边、右边和中间三个最大子序和进行比较,得到最后的结果。

    时间复杂度:O(nlogn)

代码

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        # 动态规划
        for i in range(1, len(nums)):  #range范围是[1,len(nums)) 左开右闭
            # 若当前指针指向元素之前的和小于0,则丢弃此元素之前的数列(拖后腿的丢弃!!!)
            # 当前和 = “当前值” 与 “当前值+之前最大和” 的比较中较大的那个
            # 当前索引i永远存储0~i的最大和
            nums[i] = max(nums[i]+ nums[i - 1], nums[i])
        # 返回每个索引最大和的最大值
        return max(nums)

        # 分治
        return(self.divid_and_conquer(nums, 0, len(nums)-1))
    
    def divid_and_conquer(self, nums, low, high):  # 分治函数,要输入数组和左右边界
        if low == high:  # 分治使用了递归的方法,当左指针和右指针指向同一个数,意味着已经不可再分了,则返回当前数
            return nums[low]
        mid = (low + high)//2  # 把一个数组从中间分成左右两个子数组
        max_sum_left = self.divid_and_conquer(nums,low,mid)  # 再对左子数组分成左右子子数组(递归计算左子数组中最大子序和)
        max_sum_right = self.divid_and_conquer(nums,mid+1,high)  # 同理,对右子数组分成左右子子数组(递归计算右子数组中最大子序和)
        # 计算中间最大子序和
        # 从右到左计算左边的最大子序和
        cross_suffix = 0  
        sum = 0
        for i in range(mid-1,low-1,-1):  
            sum += nums[i]
            cross_suffix = max(sum, cross_suffix)
        # 从左到右计算右边的最大子序和
        cross_prefix = 0
        sum = 0
        for i in range(mid+1,high+1):
            sum += nums[i]
            cross_prefix = max(sum, cross_prefix)
        cross_sum_max = cross_prefix + cross_suffix + nums[mid]
        # 返回左边、中间和右边的最大子序和
        return max(max_sum_left,cross_sum_max,max_sum_right)

24. 第一个只出现一次的字符

题目要求

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

在这里插入图片描述

解题思路

看到统计数字或者返回是否出现过的值,就知道要使用哈希表
下面写了两种思路哈希表的思路,一种是无序的,一种是有序的。

哈希表:

  1. 先遍历一遍字符串s,然后把所有的字符串进行统计; not char in dic 这个就很巧妙,not c in dic 整体为一个布尔值,c in dic 为判断字典中是否含有键 c
  2. 然后再遍历一遍s,在哈希表中找到首个 “数量为 1的字符”,并返回。
    时间复杂度:O(n),n是字符串的长度,需要遍历两次为O(2n),因此依然是O(n)。
    空间复杂度:O(1), s 只包含小写字母,因此空间复杂度是O(26)=O(1)的额外空间。

有序哈希表:

  1. 同样的,需要遍历一遍字符串s把所有的字符进行统计;
  2. 然后再将dic遍历一遍。然后根据dic.items() python字典的特性遍历,获取结果。
    时间复杂度和空间复杂度同哈希表方法是一样的。 参考链接

代码

class Solution:
    def firstUniqChar(self, s: str) -> str:
        # 哈希表
        if not s: return " "
        dic = {}
        for char in s:
            dic[char] = not char in dic
        for char in s:
            if dic[char]: return char
        return " "

        # 有序哈希表
        # dic = {}
        # for char in s:
        #     dic[char] = not char in dic
        # for k, v in dic.items():
        #     if v: return k
        # return " "
                

哈希表:
在这里插入图片描述
有序哈希表:
在这里插入图片描述

25. 二叉树——从上到下打印二叉树 I

题目要求

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
在这里插入图片描述

解题思路

从上到下遍历,称为二叉树的广度优先搜索(BFS),BFS通常借助“队列”的先入先出实现。

时间复杂度O(N):N是二叉树的节点数量,BFS需要循环N次。
空间复杂度O(N):最差情况下,即当树为平衡二叉树时,最多有 N/2个树节点同时在 queue 中,使用 O(N)大小的额外空间。

参考链接

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root: return []
        # 从上至下遍历,可以使用二叉树的广度优先搜索(BFS),通常借助队列的先入先出来实现
        # res, queue = [], [root]
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            # cur = queue.pop(0) # 删除第一个元素
            cur = queue.popleft()
            res.append(cur.val)
            if cur.left: 
                queue.append(cur.left)
            if cur.right: 
                queue.append(cur.right)
        return res

在这里插入图片描述

26. 二叉树——从上到下打印二叉树 II

题目要求

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
在这里插入图片描述

解题思路

从上到下遍历,称为二叉树的广度优先搜索(BFS),BFS通常借助“队列”的先入先出实现。

时间复杂度O(N):N是二叉树的节点数量,BFS需要循环N次。
空间复杂度O(N):最差情况下,即当树为平衡二叉树时,最多有 N/2个树节点同时在 queue 中,使用 O(N)大小的额外空间。

参考链接

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        # res, queue = [], [root]
        res, queue = [], collections.deque([root])
        while queue:
            temp = []
            for _ in range(len(queue)):
                # cur = queue.pop(0)
                cur = queue.popleft()
                temp.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            res.append(temp)
        return res

27. 二叉树——从上到下打印二叉树 III

题目要求

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
在这里插入图片描述

解题思路

从上到下遍历,称为二叉树的广度优先搜索(BFS),BFS通常借助“队列”的先入先出实现。

时间复杂度O(N):N是二叉树的节点数量,BFS需要循环N次。
空间复杂度O(N):最差情况下,即当树为平衡二叉树时,最多有 N/2个树节点同时在 queue 中,使用 O(N)大小的额外空间。

参考链接

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res, queue = [], collections.deque([root])
        while queue:
            temp = collections.deque()
            for _ in range(len(queue)):
                cur = queue.popleft()
                if len(res) % 2: 
                    temp.appendleft(cur.val)
                else:
                    temp.append(cur.val)
                if cur.left: 
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            res.append(list(temp))
        return res

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值