Linked List Random Node

本文介绍了一种算法,用于从链表中随机选择一个节点,确保每个节点被选中的概率相同。即使链表非常大且长度未知,该算法也能高效运行且不使用额外的空间。

一、问题描述

Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen.

Follow up:
What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?

Example:

// Init a singly linked list [1,2,3].
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
Solution solution = new Solution(head);

// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();

二、思路

问题描述:返回链表的一个随机的值。

三、代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
private:
     ListNode* head;   
    
public:
    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
 
    Solution(ListNode* head) {
        this -> head = head;
    }
    /** Returns a random node's value. */
    int getRandom() {
        int res = head -> val;
        ListNode* pNode = head -> next;
        int i = 2;
        while(pNode){
            int j = rand() % i;
            if(j == 0) res = pNode -> val;
            ++i;
            pNode = pNode -> next;
        }
        return res;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(head);
 * int param_1 = obj.getRandom();
 */


import timeit import random import time import matplotlib.pyplot as plt import matplotlib from matplotlib import font_manager import numpy as np # 设置中文字体 - 更稳健的方法 def setup_chinese_font(): """设置中文字体支持""" try: # 方法1: 直接设置支持中文的字体 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'SimSun', 'Arial Unicode MS'] plt.rcParams['axes.unicode_minus'] = False # 测试是否成功 test_fig, test_ax = plt.subplots(figsize=(1, 1)) test_ax.text(0.5, 0.5, '测试', fontsize=12) plt.close(test_fig) print("中文字体设置成功") return True except: print("中文字体设置失败,使用英文显示") plt.rcParams['font.sans-serif'] = ['DejaVu Sans', 'Arial'] return False # 在文件开头调用字体设置 chinese_supported = setup_chinese_font() class ListNode: """链表节点类""" def __init__(self, val=0, next=None): self.val = val self.next = next class LinkedList: """链表实现 - 无尾指针优化""" def __init__(self): self.head = None self.size = 0 def insert_head(self, val): """头部插入 O(1)""" new_node = ListNode(val) new_node.next = self.head self.head = new_node self.size += 1 def insert_tail(self, val): """尾部插入 O(n) - 需要遍历找到尾部""" new_node = ListNode(val) if self.head is None: self.head = new_node else: current = self.head while current.next is not None: current = current.next current.next = new_node self.size += 1 def insert_mid(self, val, index): """中间插入 O(n)""" if index <= 0: self.insert_head(val) return if index >= self.size: self.insert_tail(val) return new_node = ListNode(val) current = self.head for _ in range(index - 1): current = current.next new_node.next = current.next current.next = new_node self.size += 1 def delete_head(self): """头部删除 O(1)""" if not self.head: return None val = self.head.val self.head = self.head.next self.size -= 1 return val def delete_tail(self): """尾部删除 O(n) - 需要遍历找到尾部前一个节点""" if not self.head: return None if self.head.next is None: return self.delete_head() current = self.head while current.next.next is not None: current = current.next val = current.next.val current.next = None self.size -= 1 return val def delete_mid(self, index): """中间删除 O(n)""" if index <= 0: return self.delete_head() if index >= self.size - 1: return self.delete_tail() current = self.head for _ in range(index - 1): current = current.next val = current.next.val current.next = current.next.next self.size -= 1 return val def random_access(self, index): """随机访问 O(n)""" if index < 0 or index >= self.size: return None current = self.head for _ in range(index): current = current.next return current.val def __len__(self): return self.size class OptimizedLinkedList: """优化的链表实现 - 使用尾指针优化尾部插入""" def __init__(self): self.head = None self.tail = None self.size = 0 def insert_head(self, val): """头部插入 O(1)""" new_node = ListNode(val) new_node.next = self.head self.head = new_node if self.tail is None: self.tail = new_node self.size += 1 def insert_tail(self, val): """尾部插入 O(1) - 使用尾指针优化""" new_node = ListNode(val) if self.tail is None: self.head = self.tail = new_node else: self.tail.next = new_node self.tail = new_node self.size += 1 def insert_mid(self, val, index): """中间插入 O(n)""" if index <= 0: self.insert_head(val) return if index >= self.size: self.insert_tail(val) return new_node = ListNode(val) current = self.head for _ in range(index - 1): current = current.next new_node.next = current.next current.next = new_node self.size += 1 def delete_head(self): """头部删除 O(1)""" if not self.head: return None val = self.head.val self.head = self.head.next if self.head is None: self.tail = None self.size -= 1 return val def delete_tail(self): """尾部删除 O(n) - 即使有尾指针,单链表也无法O(1)删除尾部""" if not self.head: return None if self.head == self.tail: return self.delete_head() current = self.head while current.next != self.tail: current = current.next val = self.tail.val current.next = None self.tail = current self.size -= 1 return val def delete_mid(self, index): """中间删除 O(n)""" if index <= 0: return self.delete_head() if index >= self.size - 1: return self.delete_tail() current = self.head for _ in range(index - 1): current = current.next val = current.next.val current.next = current.next.next self.size -= 1 return val def random_access(self, index): """随机访问 O(n)""" if index < 0 or index >= self.size: return None current = self.head for _ in range(index): current = current.next return current.val def __len__(self): return self.size def create_linked_list(size): """创建普通链表测试数据""" ll = LinkedList() for i in range(size): ll.insert_tail(i) return ll def create_optimized_linked_list(size): """创建优化链表测试数据""" ll = OptimizedLinkedList() for i in range(size): ll.insert_tail(i) return ll def get_user_sizes(): """获取用户选择的数据规模""" print("\n选择测试数据规模:") print("1. 小规模测试 (100, 500, 1000)") print("2. 中规模测试 (500, 1000, 2000)") print("3. 自定义规模") choice = input("请选择 (1-3): ").strip() if choice == '1': return [100, 500, 1000, 5000, 10000] # 修改为包含10000的规模 elif choice == '2': return [500, 1000, 2000, 5000, 10000] # 修改为包含10000的规模 elif choice == '3': try: sizes_input = input("请输入数据规模 (用逗号分隔,如: 100,500,1000,5000,10000): ") sizes = [int(x.strip()) for x in sizes_input.split(',')] return [min(size, 10000) for size in sizes] # 提高最大规模限制到10000 except ValueError: print("输入格式错误,使用默认的小规模测试") return [100, 500, 1000, 5000, 10000] # 修改为包含10000的规模 else: print("无效选择,使用默认的小规模测试") return [100, 500, 1000, 5000, 10000] # 修改为包含10000的规模 def plot_performance_results(insert_results, delete_results, random_results): """绘制性能测试结果图表""" print("\n正在生成性能图表...") sizes = insert_results['sizes'] # 根据字体支持情况选择标签语言 if chinese_supported: titles = { 'main': '动态数组 vs 链表性能对比', 'insert_head': '头部插入性能\nList: O(n) vs LinkedList: O(1)', 'insert_mid': '中间插入性能\nList: O(n) vs LinkedList: O(n)', 'insert_tail': '尾部插入性能\nList: O(1) vs LinkedList: O(n)', 'delete_head': '头部删除性能\nList: O(n) vs LinkedList: O(1)', 'delete_mid': '中间删除性能\nList: O(n) vs LinkedList: O(n)', 'delete_tail': '尾部删除性能\nList: O(1) vs LinkedList: O(n)', 'random_batch': '批量随机访问 (50次)\nList: O(1) vs LinkedList: O(n)', 'random_single': '单次随机访问\nList: O(1) vs LinkedList: O(n)', 'xlabel': '数据规模', 'ylabel': '平均操作时间 (秒)' } else: titles = { 'main': 'Array vs LinkedList Performance Comparison', 'insert_head': 'Head Insert Performance\nList: O(n) vs LinkedList: O(1)', 'insert_mid': 'Middle Insert Performance\nList: O(n) vs LinkedList: O(n)', 'insert_tail': 'Tail Insert Performance\nList: O(1) vs LinkedList: O(n)', 'delete_head': 'Head Delete Performance\nList: O(n) vs LinkedList: O(1)', 'delete_mid': 'Middle Delete Performance\nList: O(n) vs LinkedList: O(n)', 'delete_tail': 'Tail Delete Performance\nList: O(1) vs LinkedList: O(n)', 'random_batch': 'Batch Random Access (50 times)\nList: O(1) vs LinkedList: O(n)', 'random_single': 'Single Random Access\nList: O(1) vs LinkedList: O(n)', 'xlabel': 'Data Size', 'ylabel': 'Average Operation Time (s)' } # 创建子图 - 调整布局 fig, axes = plt.subplots(2, 3, figsize=(20, 12)) if chinese_supported: fig.suptitle('动态数组 vs 链表性能对比', fontsize=16, fontweight='bold') else: fig.suptitle('Array vs LinkedList Performance Comparison', fontsize=16, fontweight='bold') # 插入操作对比 axes[0, 0].plot(sizes, insert_results['head_list'], 'o-', label='List', linewidth=2, markersize=6) axes[0, 0].plot(sizes, insert_results['head_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[0, 0].set_title(titles['insert_head'], fontsize=12) axes[0, 0].set_xlabel(titles['xlabel'], fontsize=10) axes[0, 0].set_ylabel(titles['ylabel'], fontsize=10) axes[0, 0].legend(fontsize=9) axes[0, 0].grid(True, alpha=0.3) axes[0, 1].plot(sizes, insert_results['mid_list'], 'o-', label='List', linewidth=2, markersize=6) axes[0, 1].plot(sizes, insert_results['mid_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[0, 1].set_title(titles['insert_mid'], fontsize=12) axes[0, 1].set_xlabel(titles['xlabel'], fontsize=10) axes[0, 1].set_ylabel(titles['ylabel'], fontsize=10) axes[0, 1].legend(fontsize=9) axes[0, 1].grid(True, alpha=0.3) axes[0, 2].plot(sizes, insert_results['tail_list'], 'o-', label='List', linewidth=2, markersize=6) axes[0, 2].plot(sizes, insert_results['tail_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[0, 2].set_title(titles['insert_tail'], fontsize=12) axes[0, 2].set_xlabel(titles['xlabel'], fontsize=10) axes[0, 2].set_ylabel(titles['ylabel'], fontsize=10) axes[0, 2].legend(fontsize=9) axes[0, 2].grid(True, alpha=0.3) # 删除操作对比 axes[1, 0].plot(sizes, delete_results['head_list'], 'o-', label='List', linewidth=2, markersize=6) axes[1, 0].plot(sizes, delete_results['head_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[1, 0].set_title(titles['delete_head'], fontsize=12) axes[1, 0].set_xlabel(titles['xlabel'], fontsize=10) axes[1, 0].set_ylabel(titles['ylabel'], fontsize=10) axes[1, 0].legend(fontsize=9) axes[1, 0].grid(True, alpha=0.3) axes[1, 1].plot(sizes, delete_results['mid_list'], 'o-', label='List', linewidth=2, markersize=6) axes[1, 1].plot(sizes, delete_results['mid_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[1, 1].set_title(titles['delete_mid'], fontsize=12) axes[1, 1].set_xlabel(titles['xlabel'], fontsize=10) axes[1, 1].set_ylabel(titles['ylabel'], fontsize=10) axes[1, 1].legend(fontsize=9) axes[1, 1].grid(True, alpha=0.3) axes[1, 2].plot(sizes, delete_results['tail_list'], 'o-', label='List', linewidth=2, markersize=6) axes[1, 2].plot(sizes, delete_results['tail_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) axes[1, 2].set_title(titles['delete_tail'], fontsize=12) axes[1, 2].set_xlabel(titles['xlabel'], fontsize=10) axes[1, 2].set_ylabel(titles['ylabel'], fontsize=10) axes[1, 2].legend(fontsize=9) axes[1, 2].grid(True, alpha=0.3) plt.tight_layout() plt.show() # 随机访问性能单独绘制 fig2, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6)) if chinese_supported: fig2.suptitle('随机访问性能对比', fontsize=16, fontweight='bold') else: fig2.suptitle('Random Access Performance Comparison', fontsize=16, fontweight='bold') ax1.plot(sizes, random_results['batch_list'], 'o-', label='List', linewidth=2, markersize=6) ax1.plot(sizes, random_results['batch_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) ax1.set_title(titles['random_batch'], fontsize=12) ax1.set_xlabel(titles['xlabel'], fontsize=10) ax1.set_ylabel(titles['ylabel'], fontsize=10) ax1.legend(fontsize=9) ax1.grid(True, alpha=0.3) ax2.plot(sizes, random_results['single_list'], 'o-', label='List', linewidth=2, markersize=6) ax2.plot(sizes, random_results['single_linked'], 's-', label='LinkedList', linewidth=2, markersize=6) ax2.set_title(titles['random_single'], fontsize=12) ax2.set_xlabel(titles['xlabel'], fontsize=10) ax2.set_ylabel(titles['ylabel'], fontsize=10) ax2.legend(fontsize=9) ax2.grid(True, alpha=0.3) plt.tight_layout() plt.show() print("性能图表生成完成!") def test_insert_operations(sizes): """使用timeit测试插入操作性能 - 修正版""" if chinese_supported: print("插入操作性能测试") print("时间复杂度说明:") print(" - 头部插入: List O(n) vs LinkedList O(1)") print(" - 中间插入: List O(n) vs LinkedList O(n)") print(" - 尾部插入: List O(1) vs LinkedList O(n)") else: print("Insert Operation Performance Test") print("Time Complexity:") print(" - Head Insert: List O(n) vs LinkedList O(1)") print(" - Middle Insert: List O(n) vs LinkedList O(n)") print(" - Tail Insert: List O(1) vs LinkedList O(n)") print("=" * 80) # 存储测试结果用于绘图 insert_results = { 'sizes': sizes, 'head_list': [], 'head_linked': [], 'mid_list': [], 'mid_linked': [], 'tail_list': [], 'tail_linked': [] } for size in sizes: if chinese_supported: print(f"\n数据规模: {size}") else: print(f"\nData Size: {size}") print("-" * 50) # 动态调整测试次数 - 对于大尺寸减少操作次数 operations = min(500, max(50, 10000 // size * 100)) if size > 1000 else min(1000, max(100, size // 10)) # 头部插入测试 list_time = min(timeit.repeat( "data.insert(0, -1)", setup=f"data = list(range({size}))", number=operations, repeat=3 )) / operations linked_time = min(timeit.repeat( "ll.insert_head(-1)", setup=f""" from __main__ import create_linked_list ll = create_linked_list({size}) """, number=operations, repeat=3 )) / operations insert_results['head_list'].append(list_time) insert_results['head_linked'].append(linked_time) if chinese_supported: print(f"头部插入 - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") else: print(f"Head Insert - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") # 中间插入测试 mid_index = max(1, size // 2) list_time = min(timeit.repeat( f"data.insert({mid_index}, -1)", setup=f"data = list(range({size}))", number=operations, repeat=3 )) / operations linked_time = min(timeit.repeat( f"ll.insert_mid(-1, {mid_index})", setup=f""" from __main__ import create_linked_list ll = create_linked_list({size}) """, number=operations, repeat=3 )) / operations insert_results['mid_list'].append(list_time) insert_results['mid_linked'].append(linked_time) if chinese_supported: print(f"中间插入 - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") else: print(f"Middle Insert - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") # 尾部插入测试 list_time = min(timeit.repeat( "data.append(-1)", setup=f"data = list(range({size}))", number=operations, repeat=3 )) / operations linked_time = min(timeit.repeat( "ll.insert_tail(-1)", setup=f""" from __main__ import create_linked_list ll = create_linked_list({size}) """, number=operations, repeat=3 )) / operations insert_results['tail_list'].append(list_time) insert_results['tail_linked'].append(linked_time) if chinese_supported: print(f"尾部插入 - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") else: print(f"Tail Insert - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") return insert_results def test_delete_operations(sizes): """删除操作测试 - 修正版:统一操作次数""" if chinese_supported: print("\n\n删除操作性能测试") print("时间复杂度说明:") print(" - 头部删除: List O(n) vs LinkedList O(1)") print(" - 中间删除: List O(n) vs LinkedList O(n)") print(" - 尾部删除: List O(1) vs LinkedList O(n)") else: print("\n\nDelete Operation Performance Test") print("Time Complexity:") print(" - Head Delete: List O(n) vs LinkedList O(1)") print(" - Middle Delete: List O(n) vs LinkedList O(n)") print(" - Tail Delete: List O(1) vs LinkedList O(n)") print("=" * 80) delete_results = { 'sizes': sizes, 'head_list': [], 'head_linked': [], 'mid_list': [], 'mid_linked': [], 'tail_list': [], 'tail_linked': [] } for size in sizes: if chinese_supported: print(f"\n数据规模: {size}") else: print(f"\nData Size: {size}") print("-" * 50) # 统一操作次数 - 根据数据规模动态调整,对于大尺寸减少操作次数 operations = min(200, max(20, 10000 // size * 50)) if size > 1000 else min(500, max(50, size // 20)) # 头部删除测试 list_head_time = min(timeit.repeat( "if data: del data[0]", setup="data = list(range(size))", globals={'size': size}, number=operations, repeat=3 )) / operations linked_head_time = min(timeit.repeat( "if ll.head: ll.delete_head()", setup=""" from __main__ import LinkedList ll = LinkedList() for i in range(size): ll.insert_tail(i) """, globals={'size': size}, number=operations, repeat=3 )) / operations delete_results['head_list'].append(list_head_time) delete_results['head_linked'].append(linked_head_time) if chinese_supported: print(f"头部删除 - List: {list_head_time:.8f}s, LinkedList: {linked_head_time:.8f}s") else: print(f"Head Delete - List: {list_head_time:.8f}s, LinkedList: {linked_head_time:.8f}s") # 中间删除测试 mid_index = size // 2 if size > 0 else 0 list_mid_time = min(timeit.repeat( f"if len(data) > {mid_index}: del data[{mid_index}]", setup="data = list(range(size))", globals={'size': size}, number=operations, repeat=3 )) / operations linked_mid_time = min(timeit.repeat( f"if ll.size > {mid_index}: ll.delete_mid({mid_index})", setup=""" from __main__ import LinkedList ll = LinkedList() for i in range(size): ll.insert_tail(i) """, globals={'size': size}, number=operations, repeat=3 )) / operations delete_results['mid_list'].append(list_mid_time) delete_results['mid_linked'].append(linked_mid_time) if chinese_supported: print(f"中间删除 - List: {list_mid_time:.8f}s, LinkedList: {linked_mid_time:.8f}s") else: print(f"Middle Delete - List: {list_mid_time:.8f}s, LinkedList: {linked_mid_time:.8f}s") # 尾部删除测试 list_tail_time = min(timeit.repeat( "if data: data.pop()", setup="data = list(range(size))", globals={'size': size}, number=operations, repeat=3 )) / operations linked_tail_time = min(timeit.repeat( "if ll.head: ll.delete_tail()", setup=""" from __main__ import LinkedList ll = LinkedList() for i in range(size): ll.insert_tail(i) """, globals={'size': size}, number=operations, repeat=3 )) / operations delete_results['tail_list'].append(list_tail_time) delete_results['tail_linked'].append(linked_tail_time) if chinese_supported: print(f"尾部删除 - List: {list_tail_time:.8f}s, LinkedList: {linked_tail_time:.8f}s") else: print(f"Tail Delete - List: {list_tail_time:.8f}s, LinkedList: {linked_tail_time:.8f}s") return delete_results def test_random_access(sizes): """随机访问性能测试 - 修正版""" if chinese_supported: print("\n\n随机访问性能测试") print("时间复杂度说明:") print(" - 随机访问: List O(1) vs LinkedList O(n)") else: print("\n\nRandom Access Performance Test") print("Time Complexity:") print(" - Random Access: List O(1) vs LinkedList O(n)") print("=" * 80) random_results = { 'sizes': sizes, 'batch_list': [], 'batch_linked': [], 'single_list': [], 'single_linked': [] } for size in sizes: if chinese_supported: print(f"\n数据规模: {size}") else: print(f"\nData Size: {size}") print("-" * 50) # 预创建测试数据 list_data = list(range(size)) linked_list = create_linked_list(size) # 生成随机索引 random_indices = [random.randint(0, size-1) for _ in range(min(50, size))] # 测试列表随机访问 list_time = min(timeit.repeat( lambda: [list_data[i] for i in random_indices], number=100, repeat=3 )) / 100 # 测试链表随机访问 linked_time = min(timeit.repeat( lambda: [linked_list.random_access(i) for i in random_indices], number=100, repeat=3 )) / 100 random_results['batch_list'].append(list_time) random_results['batch_linked'].append(linked_time) if chinese_supported: print(f"批量随机访问 {len(random_indices)} 次 - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") else: print(f"Batch Random Access {len(random_indices)} times - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") # 单次访问测试 test_index = max(0, min(size-1, size // 2)) # 列表单次访问 list_time = min(timeit.repeat( lambda: list_data[test_index], number=1000, repeat=3 )) / 1000 # 链表单次访问 linked_time = min(timeit.repeat( lambda: linked_list.random_access(test_index), number=1000, repeat=3 )) / 1000 random_results['single_list'].append(list_time) random_results['single_linked'].append(linked_time) if chinese_supported: print(f"单次访问测试 - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") else: print(f"Single Access Test - List: {list_time:.8f}s, LinkedList: {linked_time:.8f}s") return random_results def main(): """主函数""" if chinese_supported: print("动态数组 vs 链表性能测试 - 时间复杂度修正版") print("注意:本测试使用普通单链表(无尾指针),链表尾部插入为O(n)") else: print("Array vs LinkedList Performance Test - Time Complexity Fixed Version") print("Note: This test uses standard singly linked list (no tail pointer), LinkedList tail insertion is O(n)") print("=" * 80) # 获取用户选择的数据规模 sizes = get_user_sizes() if chinese_supported: print(f"\n使用数据规模: {sizes}") else: print(f"\nUsing Data Sizes: {sizes}") start_time = time.time() # 运行测试并收集结果 insert_results = test_insert_operations(sizes) delete_results = test_delete_operations(sizes) random_results = test_random_access(sizes) # 绘制性能图表 plot_performance_results(insert_results, delete_results, random_results) end_time = time.time() if chinese_supported: print(f"\n所有测试完成!总耗时: {end_time - start_time:.2f} 秒") else: print(f"\nAll tests completed! Total time: {end_time - start_time:.2f} seconds") if __name__ == "__main__": main()分析上述代码中timeit模块的使用并举出使用相关的代码片段
最新发布
10-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fullstack_lth

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

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

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

打赏作者

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

抵扣说明:

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

余额充值