面试题目总结(算法篇)

大数据:

1.40亿个非负整数找到没有出现的数字
解答:(1)使用bitmap位图,32位的int的范围是2的32次方,大概42亿,将40亿的整数进行映射为1,其他为0,新来的数据判断是否为1即可.。2的32次方bit=2的29个字节,大约500M。核心思想:将每一个数字映射成一个位。(2)将连续的数字进行压缩,比如:12356可以压缩成(1,3)和(5,2),然后新来的数字进行类似于二分查找,算法最差情况是(42-40)=2亿个结构体,每个结构体大概16亿个字节,1.6GB存下。
2.500个万个单词有一个数据结构存储。来了一个新单词判断是否在500万个其中,给一个前缀,统计有多少个单词是该前缀?
解答:字典树(前缀树)。通过增加变量区分是前缀节点还是单词节点,无重复前缀就另外建立一个新的节点,顺着节点遍历树,找到的所有单词都是以该节点为前缀的。注意在节点中增加一个变量用来计数,新增加一个就节点,就把相应的数字加一。
3.如何在10亿个数中找出前1000个数字?
解答:堆排序。如果是一台机器,就单纯堆排序,多台机器并行跑堆排序然后分治汇总。
4.40亿个非负整数找到出现两次的数
解答:bitmap方式解决。申请2的32次方2的bit数组,遍历进行,遇到第一次,就把bitArr[2num+1],bit[num*2]设置成为01,遇到第二次设置成为10,第三次设置成为11,最后再重新遍历一遍bitArr,找到为10的数。

剑指Offer

2.写单例
解答:类初始化可以避免重排序被其他线程看见。

public class Singleton { 

  private static class Holder {
      static final Singleton instance = new Singleton();
  }

  public static Singleton getInstance() {
    return Holder.instance;   
  } 

} 

3.二维数组中查找目标值
解答:找到右上角的数字和原数字进行比较,原数字>右上角的数字则行row++,原数字<右上角的数字则列column–。一般列的长度都是arr[0].length-1,行的长度arr.length-1
4.将一个字符串中的空格替换成“%20”。
解答:Java的StringBuffer或者空格加大为3倍,然后逆向复制。
5.输入一个链表,从尾到头打印链表每个节点的值。
解答:借助栈逆向打印
6.输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树
解答:找出前序的根节点,再遍历中序数组,找到根节点,递归调用找出所有有度的节点完成重建。注意点:前序和中序数组长度相同且不为空。Arrays.CopyofRange这个方法很好用
7.用两个栈实现队列
解答:一个栈负责压入,另一个负责输出。弹出时候判断出栈是否为空,空则压入入栈元素在弹出,否则直接弹出
8.把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0
解答:二分法,二分法的循环结束条件是当左边的值大于右边的值。即左指针越界右指针,由于是非递减序列,因此旋转以后可能存在数列相等的情况,则依次遍历找到最小。
mid=left+(right-left)/2,循环结束条件是right-left=1,mid=right即为最小值。
9.现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
斐波那契数列递归和非递归
10.输入一个整数,输出该数二进制表示中1的个数
解答:按位与,与操作:全为1则为1;或操作:有1则1,异或操作:相同为0,不同为1/
11…给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不得使用库函数,不需要考虑大数问题
解答:第一情况:0的N次方,注意double类型判断相等不能直接==,而是限定在一个范围内,比如a-b<0.00001;第二种情况:正数N次房;第三种情况:负数N次方。for循环相乘即可。
12.打印1到最大的n位数,相关问题(大数相加)
解答:大数问题用字符串或者数组做,注意进位carry后,较长的字符串将连续进位,如3899999,+11,那么3899999将连续进位到8,还有carry>0到最后遍历完最长字符加carry。
公式 int value = str.chatAt(0)-‘0’+carry
得到进位 carry = carry/10
得到个位 v=carry%10
打印1到N时候注意返回boolean类型,便于循环打印。
打印1到N答案
大数相加答案
13.O(1)时间删除链表节点
解答:将下一个节点的值赋给当前值,然后指针指向下一个节点。注意,如果是删除最后一个节点,那么从头遍历,倒数第二个节点的指针直接置为空。
14.输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
解答:每次只和前面一个偶数交换位置,遇到奇数停止。
15.输入一个链表,输出该链表中倒数第k个结点。
扩展题:找中间节点,使用两个指针,一个走一步,一个走两步。找到中间节点

解答:定义一快一慢两个指针,快指针走K步,然后慢指针开始走,快指针到尾时,慢指针就找到了倒数第K个节点。
16.输入一个链表,反转链表后,输出链表的所有元素。
解答:正常反之即可。
17.输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
解答:合并即可,注意最后合并剩下的部分。
18.输入两棵二叉树A,B,判断B是不是A的子结构
解答:若根节点相等,利用递归比较他们的子树是否相等,若根节点不相等,则利用递归分别在左右子树中查找。怎么算找到:两个树节点值相同,并且B树包含在A中。
19.操作给定的二叉树,将其变换为源二叉树的镜像。
解答:递归加替换


public class ReverseTreeNodeMirror {
 
	public void Mirror(TreeNode root) {
		if (root == null)
			return;
		if (root.left == null && root.right == null)
			return;
		// 交换左右子树
		TreeNode tmp = null;
		tmp = root.right;
		root.right = root.left;
		root.left = tmp;
		// 递归
		if (root.left != null)
			Mirror(root.left);
		if (root.right != null)
			Mirror(root.right);
	}

20.输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解答:正常螺旋打印就可以。注意打印完一遍,行号减少2,列号减少2
21.定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
解答:一个栈存正常值,另一个栈存最小值
22.输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列
解答:按要求作答即可。注意一个栈弹出后,注意栈中的置顶元素
23.从上往下打印出二叉树的每个节点,同层节点从左至右打印。
解答:用队列
24.输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解答:找到右子树节点的位置,第一个比根节点大的数就是右节点,并且右子树节点后的数字都要大于根节点满足则是true,否则是false,然后递归左右子树。注意右子树节点为数组头节点的情况,直接遍历右子树。
25.输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
解答:找到就打印,找不到就不打印,递归深入时候用list保存每一个节点,没有找到递归返回时候逐个删除。
26.输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
解答:先复制每一个节点,如1-》1‘-》2-》2’,再遍历复制每一个rand,最后拆分原链表和复制链表。
27.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
解答:先中序遍历,保存在队列中,然后从队列中一一连接成为双向链表
28.输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
解答:全排序

public ArrayList<String> Permutation(String str) {
    ArrayList<String> result = new ArrayList<String>() ;
    if(str == null || str.length() == 0)
        return result;
    char[] chars = str.toCharArray() ;
    TreeSet<String> temp = new TreeSet<>() ;
    Permutation(chars, 0, temp);
    result.addAll(temp) ;
    return result ;
}

public void Permutation(char[] chars, int index, TreeSet<String> result) {
    if(chars == null || chars.length == 0 )
        return ;
    if (index < 0 || index > chars.length - 1)
        return;
    if(index == chars.length-1) {
        result.add(String.valueOf(chars)) ;
    }else {
        for(int i=index ; i<=chars.length-1 ; i++) {
            swap(chars, index, i) ;
            Permutation(chars, index+1, result);
            // 回退
            swap(chars, index, i) ;
        }
    }
}

public void swap(char[] c, int a,int b) {
    char temp = c[a];
    c[a] = c[b];
    c[b] = temp;
}

去重的全排序:

bool IsSwap(char *pszStr, int nBegin, int nEnd)  
{  
    for (int i = nBegin; i < nEnd; i++)  
        if (pszStr[i] == pszStr[nEnd])  
            return false;  
    return true;  
} 



//k表示当前选取到第几个数,m表示共有多少数.  
void AllRange(char *pszStr, int k, int m)  
{  
    if (k == m)  
    {  
        static int s_i = 1;  
        cout << "第 " << s_i++ << " 个排列 " << pszStr << endl;  
    }  
    else  
    {  
        for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列  
        {  
            if (IsSwap(pszStr, k, i))  
            {  
                Swap(pszStr + k, pszStr + i);  
                AllRange(pszStr, k + 1, m);  
                Swap(pszStr + k, pszStr + i);  
            }  
        }  
    }  
}  

29.数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
解答:从第一个数开始加1,遇到相同加1,不同减1,小于0则替换当前值,最后count==1的是最终值,记得验证最终值是否符合题意。
30.输入n个整数,找出其中最小的K个数。
解答:堆排序,核心:建立堆和堆调整。
注意:
数组中一个节点的左孩子表示为left=2num+1,右孩子表示为right=2num+2
初始建堆从最后一个节点开始的,因此输入整个数组的一半。调整堆的过程,是比较父节点额两个孩子节点的大小,进行交换。并不断递归调用,直到调整完毕。
1.初始只拿k个数据进行建堆,然后对大根堆来说,只要数据中有比大根堆的堆顶元素更小的话,删除大根堆,进行替换。遍历完全部数据,输出即可。
31.求连续子数组(包含负数)的最大和
解答:数组初始开始依次相加,保留好最大和的值,如果小于0,最大和更新为当前数值。
32.输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个
解答:快速排序(三项取中)

public void recQuickSort(int left,int right){
	int size = right-left+1;
	if(size<3){
		mansual(left,right)
	}else{
		long median= medianOf3(left,right);   //三项取中,并将pivot放在最右边
		int parttion = partition(left ,right,median)
		recQickSort(left,partition-1);
		recQickSort(partition,right);
	}
}
//划分
public int partition(int left,int right ,long pivot){
	int leftPtr =left
	int right=right-1 //pivot此时在最右边,因此end端是right-1
	while(true){
		while(theArray[++left]<pivot){}
		while(theArray[++right]>pivot){}
		if(leftPtr>rightPtr){
			break
		}else{
			swap(leftPtr,rightPtr)
		}
		
	}
	//将pivo放到右边
	swap(leftPtr,right-1)
	return leftPtr;
}
//三项取中
public long medianOf3(int left,int right){
	int center = (left-right)/2
	if(theArray[left]>theArray[center]){
		swap(left,swap);
	}
	if(theArray[left]>theArray[right]){
		swap(left,right);
	}
		if(theArray[center]>theArray[right]){
		swap(center,right);
	}
	swap(center,right-1)  //将pivot放到最右边
	return theArray[right-1]
}

34.是只包含因子2、3和5的数,求从小到大的第N个丑数。
解答:数组开头为0,乘以2或3或5,将最小的数存入到数组对应的位置当中。用三个指针走,分别是因子2,因子3和因子5的指针。
35.在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
解答:用linkedHashMap保存数据,出现一次加1,最后再遍历一次linkedHashMap。
36.在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P
解答:本质是归并排序,在比较时加入全局变量count进行记录逆序对的个数,若data[start] >= data[index] ,则count值为mid+1-start。归并排序代码如下:

public void recMergeSort(int[] workSpace,int lowerBound,int upperBound){
	if(lowerBound==upperBound){		//只有一个
		return;	
	}else{
		mid=(lowerBound+upperBound)/2
		recMergeSort(workSpace,lowerBound,mid);
		recMergeSort(workSpace,mid+1,upperBound);
		merge(workSpace,lowerBound,mid+1,upperBound)
	}
}

public void merge(int[] workSpace,int lowPtr,int hight,int upperBound){
	int j=0;
	int lowerBound=lowPtr;
	int mid=hightPtr-1;
	int n = upperBound-lowerBound+1;
	while(lowPtr<mod && hightPtr<upperBound){
		if(theArray[lowPtr]<theArray[hightPtr]){
			workSpace[j++]=theArray[lowPtr++]
		}else{
			workSpace[j++]=theArray[hightPtr++]
		}
	}
	while(lowPtr<=mid){
		workSpace[j++]=theArray[lowPtr++]
	}
	while(lowPtr<=mid){
		workSpace[j++]=theArray[hightPtr++]
	}
	for(j=0;j<n;j++){
		theArray[lowerBound+j]=workSpace[j]
	}
}

37.输入两个链表,找出它们的第一个公共结点。
解答:遍历两遍列表,第一遍看两个链表的尾节点是否一致,如果一致说明链表相交,否则不相交。然后让长链表先走(长-短)步,然后同时走,相同时候就是公共点。

38.统计一个数字在排序数组中出现的次数。
解答:递归的二分查找或者非递归的二分查找,相同的mid值进行前后遍历统计。

39.1.输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
解答:递归树,递归返回比较左右数,大的加1.

39.2.输入一棵二叉树,判断该二叉树是否是平衡二叉树。
解答:左树和右树高度差小于1,等于0

40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
解答:过。
41.输出所有和为S的连续正数序列。
解答:两个指针,小指针指向加和的小数,大指针指向加和后的大数。

42.输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
解答:定义两个指针,分别从前面和后面进行遍历。间隔越远乘积越小,所以是最先出现的两个数乘积最小。

43.翻转字符串
解答:先将整个字符串翻转,然后将每个单词翻转。

44.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出
解答:先左部分逆序,再右部分逆序,最后整体逆序。

45.43.把n个骰子扔在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能出现的概率
解答:过

46.扑克牌的顺子
解答:先将5张牌排序,然后计算抽取两张之间的差值是否够0号牌插入

47.圆圈中最后剩下的数字(约瑟夫环)
解答:循环链表

public Node ykill(Node head , int m){
	if(head==null || head.next==head || m<1){
		return head;
	}
	Node last = head;
	while(last.next!=head){
		last = last.next;		//找到pre节点
	}
	int count=0;
	while(head!=last){
		if(++count==m){
			last.next=head.next;
			count=0;
		}else{
			last=last.next;
		}
		head=last.next;
	}
	return head;
}

47.求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
解答:递归,返回时boolean,用&&代替循环

48.写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
解答:过
49.将一个字符串转换成一个整数
解答:注意数字越界问题,在进行num = num*10+cur之前判断num<Integer.MinValue/10,字符串开头的正号和负号。str-‘0’ ->转成数字;

50.求树中两个节点的最低公共祖先
51.在一个长度为n的数组里的所有数字都在0到n-1的范围内,找出数组中任意一个重复的数字
解答:利用辅助空间

**52.给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…A[i-1]A[i+1]…A[n-1]。其中A[i] = 1。不能使用除法
解答:

for (size_t i = 0; i < A.size(); i++)
        {
            for (size_t j = 0; j < A.size(); j++)
            {
                if (i != j)
                    mult *= A[j];
            }
            B.push_back(mult);
            mult = 1;
        }

53.请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)
解答:当字符串只有一个字符时,进行判断,否则就有两种递归情况,(1)当模式中的第二个字符不是“”时:如果字符串第一个字符和模式中的第一个字符相匹配或是点那么字符串和模式都后移一个字符,然后匹配剩余的;如果 字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。(2)当模式中的第二个字符是“”时:如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配;如果字符串第一个字符跟模式第一个字符匹配或是点,可以有3种匹配方式:1 >模式后移2字符,相当于x*被忽略;2>字符串后移1字符,模式后移2字符;3>字符串后移1字符,模式不变,即继续匹配字符下一位,因为 * 可以匹配多位;
54.请实现一个函数用来判断字符串是否表示数值(包括整数和小数)
解答:过
55.请实现一个函数用来找出字符流中第一个只出现一次的字符。
解答:借助hashmap统计
56.一个链表中包含环,请找出该链表的环的入口结点。
解答:快慢指针遍历列表,快指针不为null则存在环,否则不存在环。存在环时候快慢指针相遇后,快指针从head头开始,改为一步走,和慢指针相同,再次相遇,则为入口节点。
57.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
解答:先新建一个头节点,然后向后查找值相同的节点,重复查找后删除
58.给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解答:因为中序遍历,先判断给的节点有没有右孩子节点,如果有,再看右孩子有没有左孩子节点,如果有,则返回该左孩子节点,否则返回右孩子节点。如果没有右孩子,给的节点有可能是处于右孩子位置的节点,也有可能是处于左孩子位置,如果是左孩子位置,直接返回父节点,如果是右孩子位置,则返回当前节点的父节点的第一个父节。
59.请实现一个函数,用来判断一颗二叉树是不是对称的
解答:利用递归进行判断,若左子树的左孩子等于右子树的右孩子且左子树的右孩子等于右子树的左孩子,并且左右子树节点的值相等,则是对称的。
60.请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,依此类推。
解答:利用两个栈的辅助空间分别存储奇数偶数层的节点
61.从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
解答:利用辅助空间链表或队列来存储节点,每层输出。
62.序列化和反序列化二叉树
解答:序列化:前序遍历二叉树存入字符串中;反序列化:根据前序遍历重建二叉树。可以用队列辅助。
63.给定一颗二叉搜索树,请找出其中的第k大的结点
解答:使用中序遍历,中序遍历就是排好序的
64.如何得到一个数据流中的中位数?
解答:创建优先级队列维护大顶堆和小顶堆两个堆,并且小顶堆的值都大于大顶堆的值,2个堆个数的差值小于等于1,所以当插入个数为奇数时:大顶堆个数就比小顶堆多1,中位数就是大顶堆堆头;当插入个数为偶数时,使大顶堆个数跟小顶堆个数一样,中位数就是 2个堆堆头平均数
65.给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值
解答:使用双端队列

leetcode:

1.最长回文子串:
解答:遍历数组每个元素,从中间向两边扩散看是否回文,此外记录回文数的大小和回文的初始位置,以便于找到回文串。
2.最长公共子序列
解答:建立动态规划表,dp[i][j]表示最长公共子序列的长度,求出递推式建立好后,使用回溯法返回序列。
3.二分查早
解答:(1)递归实现

public static int recursBearch(int[] arr , int key , int low,int hight){
		if(key<arr[low] || key>arr[hight] || low>hight ){
			return -1;
	}
	int middle = (low+hight)/2
	if(arr[middle]>key){
		return recursBearch(arr,key,low,middle-1)
	}else if(arr[middle]<key){
		return recursBearch(arr,key,middle+1,high)
	}else{
		return middle
	}
}

(2)非递归实现

public static int recursBearch(int[] arr ,int key){
	int low=0;
	int hight=arr.length-1;
	int middle=0;
	if(key<arr[low]||key>arr[high]||low>hight){
		return -1;
	}
	while(low<=high){
		middle=(low+high)/2
		if(arr[middle]>key){
			high=middle-1;
		}else if(arr[middle]<key){
			low=middle+1;
		}else{
			return middle;
		}
	}
	return -1;
}

SQL

select num as login_nums,count(*) as nums from (
	select userid,count(action_type) as num from User_Actioninfo 
			where action_type="sendMessage" and date in ('2017-11-01','2017-11-24') 
			group by userid 
			order by num desc
	)as tbl1
group by num
order by num asc;
系里前三高的工资
SELECT d.Name AS Department, e.Name AS Employee, e.Salary FROM Employee e
JOIN Department d on e.DepartmentId = d.Id
WHERE (SELECT COUNT(DISTINCT Salary) FROM Employee WHERE Salary > e.Salary
AND DepartmentId = d.Id) < 3 ORDER BY d.Name, e.Salary DESC;
求第二高的薪水:
SELECT MAX(Salary) FROM Employee 
WHERE Salary NOT IN
(SELECT MAX(Salary) FROM Employee);
where的子查询
select f.title,f.description from film as f
where f.film_id in (select fc.film_id from film_category as fc
               where fc.category_id in (select c.category_id from category as c
                                        where c.name = 'Action'));

sql语句的注意点:聚合函数sum,count,avg,max,min等运用,where和having子查询的运用。涉及到重复问题,数目问题都应该注意count函数的使用。将大问题分解成小问题,分表解决即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值