永久勘误 微软等面试100题答案V0 3版 第21-40题答案

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

微软等面试100题答案V0.3版第21-40题部分答案精选

 

作者:July 、何海涛等网友

-------------------------------------

开诚布公,接受读者质检

本文,是根据我之前上传的,微软等面试100题,的答案V0.3版[第21-40题答案]的部分答案精选,
而写。

现在,原版答案V0.3版公布出来,接受读者检验。

此文永久勘误、永久优化。同时,希望,各位不吝指正。谢谢。

===========

本微软等100题系列V0.1版,永久维护(网友,思路回复)地址:
http://topic.youkuaiyun.com/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html

ok。

-----------------------

第21题
2010年中兴面试题
编程求解:
输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,
使其和等于 m ,要求将其中所有的可能组合列出来.
//此题与第14题差不多,在次不做过多解释。
//July、本程序,经网友指出有误,但暂时没有想到解决的办法。见谅。2010/10/22。

    updated:第20题首次勘误,请参见第749、750、751楼(已经测试正确,后续将具体分析与优化):http://topic.youkuaiyun.com/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9_8.html。有任何问题,欢迎任何朋友随时指出。二零一一年四月二十日,July,updated。

  1. // 21题递归方法  
  2. //这个,没有任何问题  
  3. //from yansha  
  4. //July、updated。  
  5. #include<list>  
  6. #include<iostream>  
  7. using namespace std;  
  8.   
  9. list<int>list1;  
  10. void find_factor(int sum, int n)   
  11. {  
  12.     // 递归出口  
  13.     if(n <= 0 || sum <= 0)  
  14.         return;  
  15.       
  16.     // 输出找到的结果  
  17.     if(sum == n)  
  18.     {  
  19.         // 反转list  
  20.         list1.reverse();  
  21.         for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)  
  22.             cout << *iter << " + ";  
  23.         cout << n << endl;  
  24.         list1.reverse();      
  25.     }  
  26.       
  27.     list1.push_front(n);      //典型的01背包问题  
  28.     find_factor(sum-n, n-1);   //放n,n-1个数填满sum-n  
  29.     list1.pop_front();  
  30.     find_factor(sum, n-1);     //不放n,n-1个数填满sum   
  31. }  
  32.   
  33. int main()  
  34. {  
  35.     int sum, n;  
  36.     cout << "请输入你要等于多少的数值sum:" << endl;  
  37.     cin >> sum;  
  38.     cout << "请输入你要从1.....n数列中取值的n:" << endl;  
  39.     cin >> n;  
  40.     cout << "所有可能的序列,如下:" << endl;  
  41.     find_factor(sum,n);  
  42.     return 0;  
  43. }  
// 21题递归方法//这个,没有任何问题//from yansha//July、updated。#include<list>#include<iostream>using namespace std;list<int>list1;void find_factor(int sum, int n) {    // 递归出口    if(n <= 0 || sum <= 0)        return;        // 输出找到的结果    if(sum == n)    {        // 反转list        list1.reverse();        for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)            cout << *iter << " + ";        cout << n << endl;        list1.reverse();        }     list1.push_front(n);      //典型的01背包问题 find_factor(sum-n, n-1);   //放n,n-1个数填满sum-n list1.pop_front(); find_factor(sum, n-1);     //不放n,n-1个数填满sum }int main(){    int sum, n;    cout << "请输入你要等于多少的数值sum:" << endl;    cin >> sum;    cout << "请输入你要从1.....n数列中取值的n:" << endl;    cin >> n;    cout << "所有可能的序列,如下:" << endl;    find_factor(sum,n);    return 0;} 

第22题:
有4张红色的牌和4张蓝色的牌,主持人先拿任意两张,
再分别在A、B、C三人额头上贴任意两张牌,

A、B、C三人都可以看见其余两人额头上的牌,
看完后让他们猜自己额头上是什么颜色的牌,
A说不知道,B说不知道,C说不知道,然后A说知道了。

请教如何推理,A是怎么知道的。如果用程序,又怎么实现呢?

//July、2010/10/22
//今是老妈生日,祝福老妈,生日快乐。!:).

4张 r 4张b
有以下3种组合:
rr bb rb

1.B,C全是一种颜色
B         C       A
bb.rr    bb.rr


2.
B        C        A
bb       rr       bb/RR/BR,=>A:BR
rr       bb       =>A:BR


3.
B        C        A
BR       BB       RR/BR,   =>A:BR
//推出A:BR的原因,
//如果       A是 RR,
//那么,当ABC都说不知道后,B 最后应该知道自己是BR了。
//因为B 不可能 是 RR或BB。


4.
B        C        A
BR       BR       BB/RR/BR
//推出A:BR的原因
//i、 如果,A是 BB,那么B=>BR/RR,
//如果B=>RR,那么一开始,C就该知道自己是BR了(A俩蓝,B俩红)。(如果C.A俩蓝,那么B就一开始知道,如果C.B俩红,那么A一开始就知道,所以,论证前头,当B=>RR,那么一开始,C就该知道自己是BR)。
//如果B=>BR,那么,同样道理,C一开始也该知道自己是BR了。   

//ii、 如果A是RR....

//iii、最后,也还是推出=>A:BR
//至于程序,暂等高人。

 

第24题:反转链表
pPrev<-pNode<-pNext

ListNode* ReverseIteratively(ListNode* pHead)
{
      ListNode* pReversedHead = NULL;
      ListNode* pNode = pHead;
      ListNode* pPrev = NULL;
      while(pNode != NULL)         //pNode<=>m
      {
            ListNode* pNext = pNode->m_pNext;       //n保存在pNext下

            //如果pNext指为空,则当前结点pNode设为头。
            if(pNext == NULL)
                  pReversedHead = pNode;

            // reverse the linkage between nodes
            pNode->m_pNext = pPrev;

            // move forward on the the list
            pPrev = pNode;
            pNode = pNext;
      }
      return pReversedHead;
}

或者,这样写:
head->next -> p-> q

template<class T>
Node<T>* Reverse(Node<T>* head)
{
  p=head->next;
  while(p)
  {
     q=p->next;           //p->next先保存在q下
      p->next=head->next;  //p掉头指向head->next
     head->next=p;        //p赋给head->next
     p=q;                 //q赋给p。
                          //上俩行即,指针前移嘛...
  }
  return head;

 

第25题:
写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,
并把这个最长数字串付给其中一个函数参数outputstr所指内存。
例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,
outputstr所指的值为123456789

//leeyunce
这个相对比较简单,思路不用多说,跟在序列中求最小值差不多。未经测试。有错误欢迎指出。

int continumax(char *outputstr, char *intputstr)
{
    int i, maxlen = 0;
    char * maxstr = 0;

    while (true)
    {   
        while (intputstr && (*intputstr<'0' || *intputstr>'9')) //skip all non-digit

characters
        {   
            intputstr++;
        }

        if (!intputstr) break;

        int count = 0;
        char * tempstr = intputstr;
        while (intputstr && (*intputstr>='0' && *intputstr<='9')) //OK, these characters are

digits
        {   
            count++;
            intputstr++;
        }
        if (count > maxlen)
        {   
            maxlen = count;
            maxstr = tempstr;
        }
    }

    for (i=0; i<maxlen; i++)
    {   
        outputstr[i] = maxstr[i];
    }

    outputstr[i] = 0;

    return maxlen;
}

 

26.左旋转字符串
  题目:
  定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
    如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。
    要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。

分析:如果不考虑时间和空间复杂度的限制,
最简单的方法莫过于把这道题看成是把字符串分成前后两部分,
通过旋转操作把这两个部分交换位置。

于是我们可以新开辟一块长度为n+1的辅助空间,
把原字符串后半部分拷贝到新空间的前半部分,在把原字符串的前半部分拷贝到新空间的后半部分。
不难看出,这种思路的时间复杂度是O(n),需要的辅助空间也是O(n)。

把字符串看成有两段组成的,记位XY。左旋转相当于要把字符串XY变成YX。
我们先在字符串上定义一种翻转的操作,就是翻转字符串中字符的先后顺序。把X翻转后记为XT。显然有

(XT)T=X。
我们首先对X和Y两段分别进行翻转操作,这样就能得到XTYT。
接着再对XTYT进行翻转操作,得到(XTYT)T=(YT)T(XT)T=YX。正好是我们期待的结果。

分析到这里我们再回到原来的题目。我们要做的仅仅是把字符串分成两段,
第一段为前面m个字符,其余的字符分到第二段。
再定义一个翻转字符串的函数,按照前面的步骤翻转三次就行了。
时间复杂度和空间复杂度都合乎要求。

#include "string.h"

// Move the first n chars in a string to its end
char* LeftRotateString(char* pStr, unsigned int n)
{
    if(pStr != NULL)
    {
        int nLength = static_cast<int>(strlen(pStr));
        if(nLength > 0 || n == 0 || n > nLength)
        {
            char* pFirstStart = pStr;
            char* pFirstEnd = pStr + n - 1;
            char* pSecondStart = pStr + n;
            char* pSecondEnd = pStr + nLength - 1;
           
            // reverse the first part of the string
            ReverseString(pFirstStart, pFirstEnd);
            // reverse the second part of the strint
            ReverseString(pSecondStart, pSecondEnd);
            // reverse the whole string
            ReverseString(pFirstStart, pSecondEnd);
        }
    }
   
    return pStr;
}

// Reverse the string between pStart and pEnd
void ReverseString(char* pStart, char* pEnd)
{
    if(pStart == NULL || pEnd == NULL)
    {
        while(pStart <= pEnd)
        {
            char temp = *pStart;
            *pStart = *pEnd;
            *pEnd = temp;
           
            pStart ++;
            pEnd --;
        }
    }
}

==============

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值