分享一下我老师大神的人工智能教程!零基础,通俗易懂!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。
- // 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 --;
}
}
}
==============