经典c面试题-解答

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gg101001/article/details/88650355

1、数组a[N],1-N-1这N-1个数存放在a[n]中,其中某个数重复一次,找出重复数字,时间复杂度必须是O(n)

int do_dup(int a[],int n)
{
        int i,count=0,tmp=a[0];
        int result = -1;
        for (i=1;i<n;i++)
        {
                if(a[i]>tmp)
                        tmp=a[i];
        }
        int *b=malloc(tmp*sizeof(int));

        for(i=0;i<n;i++)
        {
                if(b[a[i]]==0)
                {
                        if(a[i]==0)
                        {
                                count+=1;
                        }
                        else
                                b[a[i]]=a[i];
                        if(count>=2)
                        {
                                result =0;
                                break;
                        }
                }
                else
                {
                        result =b[a[i]];
                        break;
                }
        }
        free(b);
        return result;
}

2、一只青蛙一次可以跳一级台阶,也可以跳两级台阶,问n级台阶有多少种跳法?(这是一个斐波那契数列问题)

设f(n)为n级台阶的跳法,那么假设第一次跳出一步则剩下n-1级台阶,可用f(n-1)表示,第一次跳出两步则剩下n-2级台阶,可用f(n-2)表示,至此f(n) = f(n-1)+f(n-2),n>2。这是一道斐波那契数列题

int F(int n)
{
    if(n == 1)
        return 1;
    int i,s3;
    int s1 = 1;
    int s2 = 1;
    for(i=2;i<=n;i++)
    {
        s3 = s1+s2;
        s1 = s2;
        s2 = s3;
    }
    return s3;
}

int F_(int n)
{
    if(n<=2)
        reurn n;
  
    return F_(n-1)+F_(n-2);
}

3、给定单向链表的头指针和一个节点指针,,定义一个函数在O(1)时间内删除该节点。(三种情况,不是尾节点,只有一个节点,是尾节点)

struct ListNode{
    int m_nValue;
    ListNode *m_pNext;
};

void DeleteNode(struct ListNode **ListHead,struct ListNode *isDelete)
{
    if(*ListNode == NULL || isDelete == NULL)
        return;
    struct ListNode *pNode = *ListHead;
    if(isDelete->m_pNext != NULL)   
    {
        struct ListNode *pNext = isDelete->m_pNext;
        isDelete->m_nValue = pNext->m_nValue;
        isDelete->m_pNext = pNext->m_pNext;
        delete pNext;
        pNext = NULL;
    }
    else if(*ListHead == isDelete)
    {
        delete isDelete;
        isDelete = NULL;
        *ListHead = NULL;
    }
    else
    {
        struct ListNode *pNode = *ListNode;
        while(pNode->m_pNext!=isDelete)
        {
            pNode=pNode->m_pNext;
        }
        pNode->m_pNext = NULL;
        delete isDelete;
        isDelete =NULL;
    }
}

4、在一个已经排好序的链表中,如何删除重复的节点?

void DeleteDuplication(struct ListNode **ListHead)
{
     if(*ListHead == NULL)
        return;
    
    struct ListNode *preNode = NULL;
    struct ListNode *pNode = *ListHead;
    while(pNode != NULL)
    {
        struct ListNde *pNext = pNode->m_pNext;
        bool bFindNode = false;
        if(pNext!=NULL && pNode->m_nValue == pNext->m_nValue)
            bFindNode = true;
        if(!bFindNode)
        {
            preNode = pNode;
            pNode = pNode->m_pNext;
        }
        else
        {
            int value = pNode->m_nValue;
            struct ListNode *pTobeDelete = pNode;
            while(pTobeDelete->m_nValue == value)
            {
                pNext = pTobeDelete->p_mNext;
                delete pTobeDelete;
                pTobeDelete = NULL;
                pTobeDelete = pNext;
            }
            if(preNode == NULL)
                *ListHead = pNext;
            else
                preNode->p_mNext = pNext;
            pNode = pNext;
        }
    }
        
}

5、正则表达式*和.的匹配实现,*表示前一个字符可以出现0或任意次,.表示前面字符可以是任意字符.

bool Match(char *str,char *rule)
{
    if(str == NULL || rule == NULL)
        return false;
    return MatchCore(str,rule);
}

bool MatchCore(char *str,char *rule)
{
    if(*str == '\0'&&rule == '\0')
        return true;
    if(*str!='\0' && rule == '\0')
        return false;
    if(*(rule+1) == '*')
    {
        if(*str==*rule ||(*str!='\0'&&*str=='.'))
        {
            return MatchCore(str,rule+2)||  //*号前面字符出现0次
                    MatchCore(str+1,rule+2)||   //*号前面字符只出现一次
                    MatchCore(str+1,rule);    //*号前面字符出现大于一次
        }
        else
            return MatchCore(str,rule+2);
    }
    if(*str==*rule || (*str!='\0'&&*str=='.'))
         return MatchCore(str+1,rule+1);
    return false;       
}

6、判断一个输入字符串是不是表示数值,如果是返回true,否则返回false。例如:+123.123e+6,-.123E-3,123.e4

bool scanUnsignedInterger(char **str)
{
    if(*str ==NULL)
        return NULL;

    char *before = *str;
    if(**str!='\0' && **str>='0' && **str<='9')
    {
        ++(*str);
    }
    return *str>before;
}


bool scanInterger(char **str)
{
    if(*str == NULL)
        return false;
    if(*str=='+' || *str=='-')
        ++(*str);
    return scanUnsignedInterger(str);
}

bool isNumber(char *str)
{
    bool bNum = scanInterger(&str);
    if(*str=='.')
    {
        ++str;
        bNum = scanUnsignedInterger(&str)||bNum;
    }
    if(*str == 'e' || *str == 'E')
    {
        ++str;
        bNum = scanInterger(&str)||bNum;
    }
    return bNum&&*str=='\0';
}

 7、输入一个整型数组,实现一个函数来是的数组内的奇数排列在数组的前面,偶数排列在数组的后面。

void reorder(int *pData,int lenght,bool (*func)(int))
{
    if(pData == NULL || length <= 0)
        return;
    int *start = pData;
    int tmp;
    int *end = pData+length-1;
    while(start < end)
    {
        while(start<end && !func(*start))
            start++;
        while(start<end && func(*end))
            end--;
        if(start<end)
        {
            tmp = *start;
            *start = *end;
            *end = tmp;
        }
    }
}

bool isEvent(int n)
{
    return (n&1)==0;
}

void ReorderOddEven(int *pData,int lenght)
{
    if(pData == NULL || length <= 0)
        return;
    reorder(pData,length);
}

8、给出一个单向的链表,实现一个函数来找链表的倒数第k个节点。

struct ListNode_{
    int m_nValue;
    ListNode_ *m_pNext;
};

typedef struct ListNode_  ListNode;

ListNode *SearchKNode(ListNode *Head,unsigned int k)
{
    if(Head == NULL)
        return NULL;
    ListNode *preNode = Head;
    ListNode *behind = NULL;
    for(int i=0;i<k-1;i++)
    {
         if(preNode->m_pNext == NULL) 
            return NULL;
        preNode = preNode->m_pNext;  
    }
    behind = Head;
    while(preNode->m_pNext!=NULL)
    {
        preNode = preNode->m_pNext;
        behind = behind->m_pNext;
    }
    return behind;
}

9、判断一个单链表是否有环?如果有找出环的入口点。

//1.首先判断环是否存在:创建两个指针p1、p2,p1走一步,p2走两步,p2指向尾节点之前能相遇则存在环,否则不存在。

ListNode *MeetingNode(ListNode *Head)
{
    if(Head == NULL)
        return NULL;
    ListNode *pSlow = Head->m_pNext;
    if(pSlow == NULL)
        return NULL;
    ListNode *pFast = pSlow->m_pNext;
    while(pFast !=NULL)
    {
        if(pFast == pSlow)
            return pFast;
        pSlow = pSlow->m_pNext;
        pFast = pFast->m_pNext;
        if(pFast != NULL)
            pFast = pFast->m_pNext;
    }
    return NULL;
}

ListNode *SearchHoopNode(ListNode *Head)
{
    ListNode *meetnode = MeetingNode(Head);
    if(meetnode == NULL)
        return NULL;
    int hoopNodeCount = 1;
    ListNode *node = meetnode;
    //找到环的节点数
    while(node->m_pNext != meetnode)
    {
        node = node->m_pNext;
        hoopNodeCount++;
    }
    ListNode *pFast = Head;
    ListNode *pSlow = Head;
    //找到环的入口节点
    for(int i = 0;i < hoopNodeCount;i++)
    {
        if(pFast == NULL)
            return NULL;
        pFast = pFast->m_pNext;
    }
    while(pFast != NULL)
    {
        pSlow = pSlow->m_pNext;
        pFast = pFast->m_pNext;
        if(pFast == pSlow)
            return pFast;
    }
    
    return NULL;
}

10、两种方式实现单链表的反转。

//递归实现
ListNode *ReverseList(ListNode *Node)
{
    if(Node == NULL || Node->m_pNext == NULL)
        return NULL;
    ListNode *p = ReverseList(Node->m_pNext);
    Node->m_pNext->m_pNext = Node;
    Node->m_pNext = NULL;
    
    return p;
}

//非递归实现

ListNode *ReverseList_(ListNode *Node)
{
    if(Node == NULL)
        return NULL;
    //记录当前节点,前一个节点和后一个节点
    ListNode *preNode = NULL;
    ListNode *node = Node;
    ListNode *pNext = NULL;
    while(node->m_pNext != NULL)
    {
        pNext = node->m_pNext;
        if(pNext->m_pNext == NULL)
            return pNext;
        node->m_pNext = preNode;
        preNode = node;
        node = pNext;
    }
    return NULL;
}


 11、合并两个链表,如链表一:1,3,5...;链表二:2,4,6;合并后就是1,2,3,4,5,6

 ListNode *MergeList(ListNode *root1,ListNode *root2)
{
    if(root1 == NULL)
        return root2;
    if(root2 == NULL)
        return root1;
    ListNode *pListHead;
    if(root1->m_nValue < root2->m_nValue)
    {
        pListHead = root1;
        pListHead->m_pNext = MergeList(root1->m_pNext,root2);
    }
    else
    {
         pListHead = root2;
         pListHead->m_pNext = MergeList(root1,root2->m_pNext);
    }
    return pListNode;
}

12、判断二叉树A是否是二叉树B的子结构,也就是子集。

bool HasSubTree(TreeNode *root1,TreeNode root2)
{
    bool result = false;
    if(root1 != NULL &&root2 != NULL)
    {
        result = Tree1HasTree2(root1,root2);
        if(!result)
            result = HasSubTree(root1->m_pLeft,root2);
        if(!result)
            result = HasSubTree(root1->m_pRight,root2);
    }
    return result;
}


bool Tree1HasTree2(TreeNode *root1,TreeNode *root2)
{
    if(root1 == NULL)
        return false;
    if(root2 == NULL)
        return true;
    if(!Equal(root1->m_pValue,root2->m_pValue))
        return false;
    return Tree1HasTree2(root1->m_pLeft,root2->m_pLeft)&&Tree1HasTree2(root1->m_pRight,root2->m_pRight);
}

bool Equal(double value1,double value2)
{
    double res = value1 - value2;
    if(res >-0.0000001 && res<0.0000001)
        return true;
    else
        return false;
}

13、编写一个函数实现二叉树镜像。

void MirrorBinaryTree(BinaryTree *root)
{
    if(root == NULL)
        return;
    if(root->m_pLeft == NULL && root->m_pRight == NULL)
        return;
    BinaryTree *pTemp = root->m_pLeft;
    root->m_pLeft = root->m_pRight;
    root->m_pRight = pTemp;
    
    if(root->m_pLeft)
        MirrorBinaryTree(root->m_pLeft);
    if(root->m_pRight)
        MirrorBinaryTree(root->m_pRight);
}

14、编写一个函数判断一颗二叉树是不是对称树。

bool isSymmetical(BinaryTree *root)
{
     return Symmetrical(root,root);   
}

bool Symmetical(BinaryTree *root1,BinaryTree *root2)
{
    if(root1 == NULL && root2 ==NULL)
        return true;
    if(root1 == NULL || root2 == NULL)
        return false;
    if(root1->m_nValue != root2->m_nValue)
        return false;
    return Symmetical(root1->m_pLeft,root2->m_pRight)&&
            Symmetical(root1->m_pRight,root2->m_pLeft);
}

15、编写一个函数实现顺时针打印矩阵

/***************************
***    1、从左到右打印
***    2、从上到下打印
***    3、从右到左打印
***    4、从下到上打印
***************************/
int PrintCircle(const char **str,int colunms,int rows)
{
    int start = 0;
    if(str == NULL || colunms <= 0 || rows <= 0)
        return -1;
    while(colunms > start*2 && rows > start*2)
    {
        PrintACircle(str,colunms,rows,start);
        start++;
    }
    return 0;
}

int PrintACircle(const char **str,int colunms,int rows,int start)
{
    int i;
    int endX = colunms-start-1;
    int endY = rows-start-1;
    
    for(i=0;i<=endX;i++)
    {
        printf("%d ",colunms[start][i]);
    }

    if(start < endY)
    {
        for(i=start+1;i<=endY;i++)
        {
            printf("%d ",colunms[endX][i]);
        }    
    }
    if(start<endX && start<endY)
    {
        for(i=endX-1;i>=start;i--)
        {
            printf("%d ",colunms[i][endY]);
        }
    }
    
    if(start<endX && start<endY-1)
    {
        for(i=endY-1;i>=start+1;i--)
        {
            printf("%d ",colunms[start][i]);
        }
    }
    return 0;
}

16、有两个序列,其中一个是入栈序列,实现一个函数判断另外一个序列是不是它的出栈序列。

bool isPopNums(const char *pPush,const char *pPop,int nLength)
{
    bool bFlag = false;
    if(pPush == NULL || pPop == NULL || nLength <= 0)
        retun false;
    char *pNextPop = pPop;
    char *pNextPush = pPush;
    while(pNextPop - pPop < nLength)
    {
        stack<int> p;
        while(p.empty() || p.top() != *pNextPop)
        {
            if(pNextPush - pPush == nLength)
                brak;
            p.push(*pNextPush);
            pNextPush++;
        }
        //如果没有一个数字匹配,则退出
        if(p.top() != pNextPop)
            break;
        p.pop();
        pNextPop++;

    } 
    if(p.empty() && pNextPop - pPop == nLength)
        bFlag = true;
    return bFlag;
}            

17、实现一个函数从上到下打印二叉树

/******************************************
*** 二叉树的前序、中序和后序遍历可以
*** 使用递归简单实现
*** 从上到下打印队列需要借助队列的先进先出的特性
*******************************************/

int PrintBinaryTree(BinaryTreeNode *root)
{
    if(root == NULL)
        return -1;
    dequeue<BinaryTreeNode *> q;
    q.push_front(root);
    while(node.size())
    {    
        BinaryTreeNode *Nodes = q.front();
        q.pop_front();
        printf("%d",Nodes->m_nValue);
        
        if(Nodes->m_pLeft)
        {
            q.push_front(Nodes->m_pLeft);
        }
        if(Nodes->m_pRight)
        {
            q.push_front(Nodes->m_pRight);
        }
    }
    return 0;
}

18、在17题的基础上,使得二叉树分层打印,即每一层对应新的一行,从左到右,从上到下。

int PrintTree(BinaryTree *root)
{
    if(root == NULL)
        return -1;
    int nPreLevel = 1;
    int nNextLevel = 0;
    std::queue<BinaryTree *> q;
    q.push(root);
    while(!q.empty())
    {
        BinaryTree *Node = q.top();
        q.pop();
        printf("%d\t",Node->m_nValue);
        
        if(Node->m_pLeft)
        {
            q.push(Node->m_pLeft);
            ++nNextLevel;
        }
        if(Node->m_pRight)
        {
            q.push(Node->m_pRight);
            ++nNextLevel;
        }
        --nPreLevel;
        if(nPreLevel == 0)
        {
            printf("\n");
            nPreLevel = nNextLevel;
            nNextLevel = 0;
        }
    }
    return 0;
}

19、实现一个函数,按之字形打印二叉树。

/*******************************
*** 第一次打印根节点
*** 第二次从右到左打印
*** 第三次从左到右打印
*** 创建两个栈,当打印的行数是奇数时,
	将其子节点按从左到右入栈1;
	当打印的偶数时,将其子节点按
	从右到左入栈
*******************************/
int Print(BinaryTree *root)
{
	std::stack<BinaryTree *> stack_[2];
	int current = 0;
	stack_[current].push(root);
	
	while(!stack_[0].empty() || !stack_[1].empty())
	{
		BinaryTree *Node = stack_[current].top();
		stack_[current].pop();
		printf("%d\t",Node->m_nValue);
		if(current == 0)
		{
			if(Node->m_pLeft)
				stack_[1].push(Node->m_pLeft);
			if(Node->m_pRight)
				stack_[1].push(Node->m_pRight);
		}
		else
		{
			if(Node->m_pRight)
				stack_[0].push(Node->m_pRight);
			if(Node->m_pLeft)
				stack_[0].push(Node->m_pLeft);
		}
		
		if(stack_[current].empty())
		{
			current = 1 - current;
			printf("\n");
		}
	}
	return 0;
}

20、实现一个函数,判断输入的一个整数序列是否为搜索二叉树的后序遍历序列。

bool isTreePostOrder(const char *s,int length)
{
    if(s == NULL || length <= 0)
        return false;
    int root_num = s[length-1];
    for(int i=0;i<length-1;i++)
    {
        if(s[i] > root_num)
            break;
    }
    for(int j =i;j<length-1;j++)
    {
        if(s[j] <= root_num)
            return false;
    }
    bool Left = true;
    bool Right = true;
    if(i < length-1)
        Left = isTreePostOrder(s,i);
    if(j > i)
        Right = isTreePostOrder(s+i,length-i-1);

    return (Left&Right);
}

21、输入一个的整数,判断二叉树中存在多少条路径,使得路径节点和等于输入整数。

bool FindPath(BinaryNode *root,int number)
{
	if(root == NULL)
		return false;
	std::vector<int> path;
	int sum = 0;
	FindPath(root,number,path,sum);
	return true;
}

void FindPath(BinaryNode *root,int number,std::vector<int> &path,int sum)
{
	path.push_back(root->m_nValue);
	sum += root->m_nValue;
	if(root->m_pLeft==NULL && root->m_pRight==NULL && sum == number)
	{
		for(vector<int>::iterator it=path.begin();it<path.end();it++)
		{
			cout<<*it<<endl;
		}
		sum -= root->m_nValue;
	}
	if(root->m_pLeft)
		FindPath(root->m_pLeft,number,path,sum);
	if(root->m_pRight)
		FindPath(root->m_pRight,number,path,sum);
	path.pop_back();
}

22、复杂链表的复制

/********************************************
*** 分为三步进行链表的复制
*** 1、将链表扩大一倍,复制每一个节点并插入该节点的后面
*** 2、完成对m_pOther指针的指向
*** 3、分拆链表,节点是偶数的是新链表,节点为奇数则为原始链表
*********************************************/
struct LIST{
	int m_nValue;
	struct LIST *m_pNext;
	struct LIST *m_pOther;//该指针指向链表的任意节点,也可以是NULL
};

bool connectList(struct LIST *pHead)
{
	if(pHead == NULL)
		return false;
	
	struct LIST *pNode = pHead;
	
	while(pNode != NULL)
	{
        struct LIST *pcloneNode =new LIST();
		pcloneNode->m_nValue = pNode->m_nValue;
		pcloneNode->m_pNext = pNode->m_pNext;
        pcloneNode->m_pOther = NULL;
		pNode->m_pNext=pcloneNode;
		pNode = pcloneNode->m_pNext;
	}
	return true;
}

bool connectOtherNode(struct LIST *pHead)
{
	if(pHead == NULL)
		return false;
	struct LIST *pNode = pHead;
	
	while(pNode != NULL)
	{
        struct LIST *pCloned = pNode->m_pNext;
		if(pNode->m_pOther != NULL)
		{
			pCloned->m_pOther = pNode->m_pOther->m_pNext;
		}
		pNode = pCloned->m_pNext;
	}
	return true;
}

struct LIST *reconnetList(struct LIST *pHead)
{
	if(pHead == NULL)
		return NULL;
	struct LIST *pcloneNode = NULL;
	struct LIST *pNode = pHead;
	struct LIST *pcloneHead = NULL;
	
	if(pNode->m_pNext != NULL)
	{
		pcloneHead = pcloneNode = pNode->m_pNext;
		pNode->m_pNext = pcloneNode->m_pNext;
		pNode = pNode->m_pNext;
	}
	
	while(pNode != NULL)
	{
		pcloneNode->m_pNext = pNode->m_pNext;
		pcloneNode = pcloneNode->m_pNext;
        pNode->m_pNext = pcloneNode->m_pNext;
		pNode = pNode->m_pNext;
	}
	return pcloneHead;
}

struct LIST *Clone(struct LIST *pHead)
{
    connectList(pHead);
    connectOtherNode(pHead);
    return reconnectList(pHead);
}

23、已知一颗二叉树,实现一个函数将二叉树变成排好序的双向链表。

BinaryNode *CreatList(BinaryNode *root)
{
	if(root == NULL)
		return NULL;
	BinaryNode *pOfList;
	CreatListNode(root,&pOfList);
	//返回头结点
	BinaryNode *pOfListHead = pOfList;
	while(pOfListHead != NULL && pOfListHead->m_pLeft != NULL)
	{
		pOfListHead = pOfListHead->m_pLeft;
	}
	
	return pOfListHead;
}

void CreatListNode(BinaryNode *root,BinaryNode **pOfList)
{
	if(root == NULL)
		return;
	BinaryNode *pOfListNode = *root;
	if(root->m_pLeft != NULL)
		CreatListNode(root->m_pLeft,pOfList);
			
	pOfListNode->m_pLeft = *pOfList;
	if(*pOfList != NULL)
		(*pOfList)->m_pRight = pOfListNode;
	*pOfList = root;
	
	if(root->m_pRight != NULL)
		CreatListNode(root->m_pRight,pOfList);
}

24、求一个整型数组中连续元素和的最大值,即[1,-3,4,5,7,-1,9,-4]数组的最大和就是4+5+7-1+9 = 24

bool isRightInput = true;
int GreateSum(int *s,int length)
{
	int i;
	int curSum = 0;
	int greatSum = 0;
	if(s == NULL || length <= 0)
	{
		isRightInput = false;
		return 0;
	}
	for(i=0;i<length;i++)
	{
		if(curSum <= 0)
			curSum = s[i];
		else
			curSum += s[i];
		if(curSum > greatSum)
			greatSum = curSum
	}
	return greatSum;
}

25、一个数字串“01234567891011.....”排列,第零位是0,第五位是5,实现一个函数输入一个整数N,求第N位的数字是多少?

int numbersOfDigits(int digits)
{
	if(digits <= 0)
		return 0;
	//0-9有九位(0是第0位)10-99有2*90=180位
	return 9*pow(10,digits-1);
}

int GetNbitNum(int index,int digits)
{
	if(index < 0 || digits < 1)
		return -1;
	int i;
	//求出第n位在哪个整数中,比如在370
	int number = pow(10,digits-1) + index/digits;
	//求出在该整数的第几位,比如第一位是7
	int num = digits - index%digits;
	for(i=1;i<num;i++)
		number /= 10;
	return number%10;
}

int GetNum(int index)
{
	if(index <= 9 )
		return index;
	int digits = 1;
	while(index)
	{
		int number = numbersOfDigits(digits);
		if(index < number*digits)
			return GetNbitNum(index,digits);
		//计算index位于哪一个区间,0-9,10-99,100-999......
		index -= number*digits;
		digits++;
	}
	return -1;
}

26、编写一个函数实现atoi的功能

enum {eValid=0,eInValid};
int g_Status = eInValid;
int StrToInt(const char *str)
{
    bool flag = false;
    long long num = 0;
    if(str != NULL && *str != '\0'){
        if(*str == '+'){
            str++;
            flag = true;
        }
        else if(*str == '-'){
            str++;    
        }
        if(*str != '\0')
            num = StrToIntCore(str,flag);
    }
    return (int)num;
}

long long StrToIntCore(const char *str,bool flag)
{
    long long num = 0;
    int flag_ = flag?1:-1;
    while(*str !='\0')
    {
        if(*str>='0' &&*str<='9')
        {
            num = 10*num + flag_*(*str-'0');
            if((flag && num>0x7FFFFFFF)||(!flag && num < 0x80000000))
            {
                num =0 ;
                break;
            }
        }
        else
        {
            num = 0 ;
            break;
        }
        str++:
    }
    if(*str == '\0')
        g_Status = g_Valid;
    return num;
}

 题目出处:以笔上试题均出自书本剑指Offer第二版

展开阅读全文

没有更多推荐了,返回首页