名企招聘经典面试编程题集锦[第21-30题]

21、反转链表
定义一个函数,输入一个链表的结点,反转该链表并输出反转后链表的头结点。

listNode* ReverseList(listNode* head)
{
	if(head==NULL)
		return NULL;
	listNode* first = NULL;
	listNode* second = head;
	head = head->next;
	while (second!=NULL)
	{
		second->next = first;
		first = second;
		second = head;
		if(head!=NULL)
			head = head->next;
	}
	return first;
}

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

int continumax(char *outputstr,char *intputstr)
{
	if(outputstr==NULL || intputstr==NULL || *intputstr=='\0')
		return -1;
	char* start = NULL;
	int length = 0;
	char* startHelper = NULL;
	int lengthHelper = 0;
	for (char* ch = intputstr;*ch!='\0';++ch)
	{
		if(*ch<='9' && *ch >='0')
		{
			if(startHelper==NULL)
				startHelper = ch;
			++lengthHelper;
		}
		else
		{
			if(lengthHelper>length)
			{
				start = startHelper;
				length = lengthHelper;
			}
			startHelper = NULL;
			lengthHelper = 0;
		}
	}
	if(start!=NULL)
	{
		int i = 0;
		for(;i!=length;++i)
			*(outputstr+i) = *(start+i);
		*(outputstr+i)='\0';
		return length;
	}
	else
		return -1;
}

23、左旋转字符串

定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。

如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。
要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。

void Reverse(char* first,char* last)
{
	if(first==NULL || last==NULL || first-last>0)
		return;
	while (first<last)
	{
		char temp = *first;
		*first++ = *last;
		*last-- = temp;
	}
}

void LeftRotate(char* str,int n)
{
	if(str == NULL || n<1)
		return;
	char* first = str;
	char* last =str;
	while(*last!='\0')
		++last;
	--last;
	Reverse(first,last);
	last-=n;
	Reverse(first,last);
	first=last+1;
	last+=n;
	Reverse(first,last);
}

24、整数的二进制表示中1的个数
输入一个整数,求该整数的二进制表达中有多少个1。
例如输入10,由于其二进制表示为1010,有两个1,因此输出2。

int SumOfOne(int n)
{
	int k = 1;
	int ret =0 ;
	for (int i = 0; i!=32;++i)
	{
		if(k&n)
			++ret;
		k=k<<1;
	}
	return ret;
}

//更棒的解法
int SumOfOne(int n)
{
	int ret = 0;
	while (n)
	{
		++ret;
		n = n & (n-1);
	}
	return ret;
}

25、和为n的连续正数序列
输入一个正数n,输出所有和为n连续正数序列。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
分析:这是网易的一道面试题。

void FindContinuousSequence(int num)
{
	if(num<3)
		return;
	int start = 1;
	int end = 2;
	int sum = start + end;
	while (start!=end)
	{
		if(sum<num)
		{
			++end;
			sum+=end;
		}
		else if(sum>num)
		{
			sum-=start;
			++start;
		}
		else
		{
			int temp = start;
			while(temp<=end)
				cout<<temp++<<" ";
			cout<<endl;
			++end;
			sum+=end;
		}
	}
}

26、字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串
abc、acb、bac、bca、cab和cba。

分析:这是一道很好的考查对递归理解的编程题,
因此在过去一年中频繁出现在各大公司的面试、笔试题中。

void Permutation(char* str,char* begin);
void Permutation(char* str)
{
	if(str == NULL)
		return;
	Permutation(str,str);
}

void Permutation(char* str,char* begin)
{
	if(*begin == '\0')
		cout<<str<<"  ";
	for (char* ch = begin ; *ch!='\0';++ch)
	{
		char temp  = *begin;
		*begin = *ch;
		*ch = temp;
		Permutation(str,begin+1);
		temp  = *begin;
		*begin = *ch;
		*ch = temp;
	}
}

27、调整数组顺序使奇数位于偶数前面

输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,
所有偶数位于数组的后半部分。要求时间复杂度为O(n)。

void OddBeforeEven(int* data,int length)
{
	if(data == NULL || length <1)
		return;
	int* start = data;
	int* end = data+length-1;
	while (start<end)
	{
		while(*start & 1)
			++start;
		while(!(*end & 1))
			--end;
		if(start<end)
		{
			int temp = *start;
			*start = *end;
			*end = temp;
		}
	}
}

28、赋值运算符
题目:类CMyString的声明如下:
class CMyString
{
public:
      CMyString(char* pData = NULL);
      CMyString(const CMyString& str);
      ~CMyString(void);
      CMyString& operator = (const CMyString& str);

private:
      char* m_pData;
};
请实现其赋值运算符的重载函数,要求异常安全,即当对一个对象进行赋值时发生异常,对象的状态不能改变。

CMyString& CMyString::operator =(const CMyString& str)
{
	if (this != &str)
	{
		CMyString tempStr(str);
		char* temp = tempStr.m_pData;
		tempStr.m_pData = m_pData;
		m_pData = temp;
	}
	return *this;
}

29、用两个栈实现队列
用两个栈实现一个队列,队列声明如下,请实现它的两个函数appendTail和deleteHead,
分别完成在队列尾部插入结点和在队列头部删除结点的功能。
template<typename T> class MyQueue
{
public:
	MyQueue(){}
	~MyQueue(){}
	void appendTail(const T&);
	T deleteHead();
private:
	stack<T>stack1;
	stack<T>stack2;
};

template<typename T> MyQueue<T>::appendTail(const T& data)
{
	stack1.push(data);
}

template<typename T> T MyQueue<T>::deleteHead()
{
	if(stack2.empty())
	{
		if(stack1.empty())
			throw exception("queue is empty!");
		else
		{
			while(!stack1.empty())
			{
				stack2.push(stack1.top());
				stack1.pop();
			}
		}
	}
	T ret = stack2.top();
	stack2.pop();
	return ret;
}

30、从尾到头输出链表

题目:输入一个链表的头结点,从尾到头反过来输出每个结点的值。

//如果可以修改链表,则先反转链表,再逐个输出;如果不可以,则借助于栈。
void PrintFromTailToHead(listNode* head)
{
	if(head==NULL)
		return;
	stack<listNode*> helper;
	while(head!=NULL)
	{
		helper.push(head);
		head = head->next;
	}
	while (!helper.empty())
	{
		cout<<helper.top()->value<<"  ";
		helper.pop();
	}
	cout<<endl;
}

欢迎大家访问我的独立技术博客 道合|SameIdeal.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值