Microsoft经典面试题集锦

本文解析了六个算法挑战题目,包括检查字符串是否为整数、在排序数组中查找给定数出现次数、寻找平面上N个点中斜率最大的直线、判断数列中五个数值是否连续相邻、找出二叉树上任意两节点的最近共同父节点及在排序二叉树中寻找最接近中值的节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 检查字符串是否为整数,是则输出该整数

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

const int max = 10;
bool checkNum(string &str) {
	string::iterator it;
	int i;
	long s = 0;
	for(it = str.begin(), i = 0; it != str.end() && i < max; i++, it++) {
		if(!isdigit(*it)) return false;
		s = s*10 + (*it) - '0';
	}
	if(i >= max) {
		cerr<<"整数溢出!"<<endl;
	}
	cout<<str<<"对应的整数是:"<<s<<endl;
	return true;
}

void main() {
	string str;
	cin>>str;
	if(!checkNum(str)) {
		cerr<<str<<"不是整数"<<endl;
	}
}





二 在排序好的整数数组中查找给定数出现的次数

#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <ctime>

using namespace std;

#define ERROR -1
const int M = 1000;
class Solution {
private:
	int N;
	vector<int>v;

	int BinaryLocate(int low, int high, int x) {
		int mid = (low + high) / 2;
		if(low <= high) {
			if(v[mid] == x) return mid;
			else if(v[mid] > x) return BinaryLocate(low, mid-1, x);
			else return BinaryLocate(mid+1, high, x);
		}
		else return ERROR;
	}
public:
	Solution(int n) {
		if(n <= 0 || n > M) {
			cerr<<"参数错误, 程序退出!"<<endl;
			exit(1);
		}
		N = n;
		int i;
		srand(unsigned(time(0)));
		for(i = 0; i< N; i++) {
			int x = rand() % N;
			v.push_back(x);
		}
		sort(v.begin(), v.end());
		copy(v.begin(), v.end(), ostream_iterator<int>(cout," "));
	}

	int JustDoIt(const int e) {
		int i = BinaryLocate(0, v.size() - 1, e);
		if(i < 0) {
			cerr<<"不能找到"<<e<<endl;
			return ERROR;
		}
		int cnt =1;
		int j = i;
		/*
		 * j指向第一次出现v[i]的位置,如 1 3 3 3 4 5 6
		 * j会指向位置1
		*/
		while(j > 0 && v[j] == v[j-1]) j--;
		i = j;
		while(i < v.size() -1 && v[i] == v[i+1]) {
			cnt++;
			i++;
		}
		return cnt;
	}
};

void main() {
	int N = 20;
	Solution s(N);
	int e;
	cout<<"请输入0到"<<N-1<<"之间的整数:"<<endl;
	cin>>e;
	if(!cin.good()) {
		cerr<<"输入错误!"<<endl;
		exit(1);
	}
	int cnt = s.JustDoIt(e);
	if(cnt != ERROR) {
		cout<<e<<"出现的次数为:"<<cnt<<endl;
	}
}



三 平面上N个点,每两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点(斜率不存在的情况不考虑)。

#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

const double min = - 99999;   // 当两个点的横坐标相同时, 它们的斜率为min

const double minNum = -10000;  // 最小的数
const double maxNum = 10000;  // 最大的数

class Point {
public:
	double x;
	double y;
	Point(double X = 0, double Y = 0) {
		x = X;
		y = Y;
	}
	bool operator < (const Point & p) {
		return x < p.x;
	}
	friend ostream operator <<(ostream &os, const Point &point) {
		os<<"["<<point.x<<","<<point.y<<"]"<<endl;
		return os;
	}
};

/*
 * 先对点向量按横坐标排序, 然后计算排序后相邻点的斜率
*/

class Solution {
private:
	vector<Point>v;   // 点向量
	int n;            // 点的个数     
	double maxK;      // 最大的斜率
public:
	Solution(int N) {
		if(N <= 0) {
			cerr<<"参数不合法, 程序退出!"<<endl;
			exit(1);
		}
		n = N;
		int i;
		double x, y;
		for(i = 0; i < n; i++) {
			cout<<"第"<<i<<"个点:"<<endl;
			cin>>x>>y;
			if(!cin.good()) {
				cout<<"输入不合法, 程序退出!"<<endl;
				exit(1);
			}
			if(x < minNum || x > maxNum) {
				cerr<<"参数不合法, 程序退出!"<<endl;
				exit(1);
			}
			if(y < minNum || y > maxNum) {
				cerr<<"参数不合法, 程序退出!"<<endl;
				exit(1);
			}
			Point p = Point(x, y);
			v.push_back(p);
		}
		maxK = 0;
	}
	void JustDoIt() {
		sort(v.begin(), v.end());     // 按点的横坐标x快速升序排序
		int len = n - 1;
		double *k = new double(len);    // 斜率数组

		int i;
		for(i = 0; i < n-1; i++) {
			k[i] = slop(v[i], v[i+1]);      // 求出相邻两个点的斜率
		}
		maxK = *max_element(k, k + len);      // 求出数组k中最大值
		i = max_element(k, k + len) - k;	    // 求出数组k中最大值的索引
		showmaxK();

		cout<<v[i];                         // 求出哪两个点的斜率最大
		cout<<v[i+1];
	}
	double slop(const Point& start, const Point& end) {
		if(end.x - start.x == 0) return min;
		return 1.0 * (end.y - start.y) / (end.x - start.x);
	}
	void showV() {
		vector<Point>::iterator it;
		for(it = v.begin(); it != v.end(); it++) {
			cout<<*it;
		}
	}
	void showmaxK() {
		cout<<"最大斜率是:"<<maxK<<endl;
	}
};

void main() {
	Solution s(10);
	s.JustDoIt();
}

测试:



一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
注意:
- 5个数值允许是乱序的。比如: 8 7 5 0 6
- 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4
- 0可以多次出现。
- 复杂度如果是O(n2)则不得分。

#include <iostream>
#include <cstdlib>
#include <vector>
#include <ctime>
#include <algorithm>

using namespace std;

const int Max = 65535;
class Solution {
private:
	vector<int>v;
	vector<int>selection;
	int n;
	int m;
public:
	Solution(int N) {
		if(N <= 0) {
			cerr<<"参数不合法, 程序退出!"<<endl;
			exit(1);
		}
		if(!cin.good()) exit(1);
		n = N;
		int i;
		srand(unsigned(time(NULL)));
		for(i = 0; i < n; i++) {
			int e = rand() % Max;
			if(v.empty() == true) v.push_back(e);
			else if(e == 0) {  
				v.push_back(e);
			}
			else if(find(v.begin(), v.end(), e) == v.end())  {
				v.push_back(e);
			}
		}
	}
	/*
	 * 随机选择M个整数
	*/
	void RandomSelectM(int M) {
		if(M <= 0) {
			cerr<<"参数不合法, 程序退出!"<<endl;
			exit(1);
		}
		if(!cin.good()) exit(1);
		m = M;
		srand(unsigned(time(NULL)));
		int i = 0;
		int j;
		while(i < m) {
			j = rand() % v.size();               //随机产生一个索引号
			if(selection.empty() == true) {
				selection.push_back(v[j]);
				i++;
			}
			/*
			 * 刚随机选择的数之前没有选择过
			*/
			else if(find(selection.begin(), selection.end(), v[j]) == selection.end()) {
				selection.push_back(v[j]);
				i++;
			}
		}
	}
	
	void IsSequence() {
		int Max = *max_element(selection.begin(), selection.end());    // 找到数组中最大值
		int Min = *min_element(selection.begin(), selection.end());
		if(Max - Min <= m - 1) {
			cout<<"这"<<m<<"个整数连续"<<endl;
		}
		else cout<<"这"<<m<<"个整数不连续"<<endl;
	}
	void show() {
		vector<int>::iterator it;
		cout<<"这"<<n<<"个数是:";
		for(it = v.begin(); it != v.end(); it++) {
			cout<<*it<<" ";
		}
		cout<<endl;
		cout<<"从这"<<n<<"个数中选择"<<m<<"个数是:";
		for(it = selection.begin(); it != selection.end(); it++) {
			cout<<*it<<" ";
		}
		cout<<endl;
	}
};
void main() {
	Solution s(10);
	s.RandomSelectM(5);
	s.show();
	s.IsSequence();
}


五 设计一个算法,找出二叉树上任意两个结点的最近共同父结点。复杂度如果是O(n2)则不得分。

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

template<class T>
/*
 * 二叉树结点类
*/
class BinNode {
	public:
		T data;
		BinNode<T>*lchild;
		BinNode<T>*rchild;
		BinNode<T>(T e =NULL, BinNode<T>*left = NULL, BinNode<T>*right = NULL) {
			data = e;
			lchild = left;
			rchild = right;
		}
		BinNode<T>(const BinNode<T> &binNode) {
			data = binNode.data;
			lchild = binNode.lchild;
			rchild = binNode.rchild;
		}
		BinNode<T> operator = (const BinNode<T> &binNode) {
			data = binNode.data;
			lchild = binNode.lchild;
			rchild = binNode.rchild;
			return *this;
		}
};

/*
 * 二叉树类
*/
template<class T>
class BinTree {
	private:
		BinNode<T>*root;       // 二叉树根结点指针
		BinNode<T>*result;     // 最近公共父结点指针

		/*
		 * 递归构造二叉树 
		*/
		void CreateBinTree(BinNode<T>*&p) {
			T data;
			cin>>data;
			if(data != "#") {
				p = new BinNode<T>(data);
				CreateBinTree(p->lchild);
				CreateBinTree(p->rchild);
			}
		}
		/*
		 * 前序遍历二叉树
		*/
		void Tranvser(BinNode<T>*p) {
			if(p != NULL) {
				cout<<p->data<<" ";
				Tranvser(p->lchild);
				Tranvser(p->rchild);
			}
		}
		bool NearestParent(BinNode<T>*root, BinNode<T>*parent, BinNode<T>*&result, const T&a, const T&b) {
			/*
			 * left = true 表示a或b在当前结点的左子树中
			*/
			bool left = false;       
			/*
			 * right = true 表示a或b在当前结点的右子树中
			*/
			bool right = false;
			/*
			 * 从当前结点的左子树返回后, left = true表示a或b在它的左子树中
			*/
			if(!result && root->lchild) left = NearestParent(root->lchild, root, result, a, b);
			/*
			 * 从当前结点的右子树返回后, right = true表示a或b在它的右子树中
			*/
			if(!result && root->rchild) right = NearestParent(root->rchild, root, result, a, b);
			/*
			 * cur = true 表示a或b就是当前正在访问的结点
			*/
			bool cur = false;

            // 当root指向的当前结点是a或b时
			if(root->data == a || root->data == b) {
				cur = true;
			}
			// 此时a和b位于同一分支或者a和b位于不同分支
			if(!result && cur + left + right == 2) {
				if(cur == true) {      // 此时a和b同时位于左分支或右分支
					result = parent;
				}
				else result = root;
			}
			return left | right | cur;
		}
	public:
		BinTree() {
			root = NULL;
			CreateBinTree(root);
		}
		void Tranvser() {
			Tranvser(root);
		}
		void NearestParent(const T&a, const T&b) {
			result = NULL;
			NearestParent(root, NULL, result, a, b);
		}
		void getResult() {
			cout<<result->data<<endl;
		}
};

void main() {
	BinTree<string>binTree;
	cout<<"输入的二叉树是:";
	binTree.Tranvser();
	cout<<endl;
	string a, b;
	cout<<"请输入两个结点值:";
	cin>>a>>b;
	binTree.NearestParent(a, b);
	binTree.getResult();
	cout<<a<<"和"<<b<<"最近公共父结点是:";
	binTree.getResult();
}

测试:



六 一棵排序二叉树,令 f=(最大值+最小值)/2, 设计一个算法,找出距离f值最近、大于f值的结点。

#include <iostream>
#include <cstdlib>

using namespace std;

template<class T>
class BSTNode {
	public:
		T data;
		BSTNode<T>*lchild;
		BSTNode<T>*rchild;

		BSTNode(const T &e, BSTNode<T>*left = NULL, BSTNode<T>*right = NULL) {
			data = e;
			lchild = left;
			rchild = right;
		}

		BSTNode(const BSTNode<T> &bst) {
			data = bst.data;
			lchild = bst.lchild;
			rchild = bst.rchild;
		}

		BSTNode<T>& operator =(const BSTNode<T> &bst) {
			data = bst.data;
			lchild = bst.lchild;
			rchild = bst.rchild;
			return *this;
		}
};

template<class T>
class BST {
	friend class Solution;
	private:
		BSTNode<T>*root;
		int N;
		/*
		 * 后序遍历
		*/
		void tranverseBST(BSTNode<T>*root) {
			if(root) {
				tranverseBST(root->lchild);
				cout<<root->data<<" ";
				tranverseBST(root->rchild);
			}
		}
		/*
		 * 插入结点
		*/
		void insertBST(BSTNode<T>*&root, const T& e) {
			if(root == NULL) {
				root = new BSTNode<T>(e);
			}
			else if(e >= root->data) {
				insertBST(root->rchild, e);
			}
			else insertBST(root->lchild, e);
		}

	public:
		BST() {
			root = NULL;
		}

		void createBST(int n) { 
			if(n <= 0) {
				cerr<<"参数错误, 程序退出!";
				exit(1);
			}
			int i;
			T e;
			for(i = 0; i < n; i++) {
				cout<<"请输入第"<<i<<"个值:";
				cin>>e;
				insertBST(root, e);
			}
		}
		void tranverseBST() {
			tranverseBST(root);
		}
};

class Solution {
private:
	BST<double>bst;
	double max;
	double min;
	double f;
	bool find;
	BSTNode<double>*result;

	void Setmax(BSTNode<double>*node) {
		while(node->rchild) {
			node = node->rchild;
		}
		max = node->data;
	}

	void Setmin(BSTNode<double>*node) {
		while(node->lchild) {
			node = node->lchild;
		}
		min = node->data;
	}

	void Setf() {
		f = (min + max)/2;
	}

	void Setresult(BSTNode<double>*node) {
		if(node) {
			if(find == false) { 
				Setresult(node->lchild);
			}
			if(find == false && node->data > f) {
				result = node;
				find = true;

			}
			if(find == false) {
				Setresult(node->rchild);
			}
		}
	}
public:
	Solution(int n):max(0), min(0), result(NULL), find(false) {
		bst.createBST(n);

	}

	void JustDoIt() {
		Setmax(bst.root);
		Setmin(bst.root);
		Setf();
		Setresult(bst.root);
	}
	void show() {
		cout<<"最大值是:"<<max<<endl;
		cout<<"最小值是:"<<min<<endl;
		cout<<"中值是:"<<f<<endl;
		cout<<"最接近中值的结点是:"<<result<<endl;
		cout<<"最接近中值的值是:"<<result->data<<endl;
	}
};

void main() {
	Solution s(6);
	s.JustDoIt();
	s.show();
}


测试:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值