面试100题之我的解答

利用static变量,两个变量必须都为static,因为它们的状态需要记住

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

struct Node
{
	Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
	int data;
	Node *left;
	Node *right;
};

Node* construct()
{
	Node *node7 = new Node(16);
	Node *node6 = new Node(12);
	Node *node5 = new Node(8);
	Node *node4 = new Node(4);
	Node *node3 = new Node(14, node6, node7);
	Node *node2 = new Node(6, node4, node5);
	Node *node1 = new Node(10, node2, node3);

	return node1;
}

Node* convert(Node *root)
{
	if (root == NULL)
		return NULL;
	static Node *head = NULL;
	static Node *pHead;

	convert(root->left);
	if (head == NULL)
	{
		head = root;
		pHead = head;
	}
	else
	{
		pHead->right = root;
		root->left = pHead;
		pHead = root;
	}
	convert(root->right);

	return head;
}

void print(Node *head)
{
	if (head == NULL)
		return;

	while (head != NULL)
	{
		cout << head->data << " ";
		head = head->right;
	}
}

void main()
{
	Node *root = construct();
	Node *head = convert(root);
	print(head);
}
可以利用传值:

Node* convert(Node *root, Node *&head)
{
	if (root == NULL)
		return NULL;
	static Node *pHead;

	convert(root->left, head);
	if (head == NULL)
	{
		head = root;
		pHead = head;
	}
	else
	{
		pHead->right = root;
		root->left = pHead;
		pHead = root;
	}
	convert(root->right, head);

	return head;
}

还可以循环:

Node* convert(Node *root)
{
	if (root == NULL)
		return NULL;

	stack<Node*> nstack;
	Node *pRoot = root;
	Node *head = NULL;
	Node *pHead = head;

	while (pRoot != NULL || !nstack.empty())
	{
		while (pRoot != NULL)
		{
			nstack.push(pRoot);
			pRoot = pRoot->left;
		}
		pRoot = nstack.top();
		nstack.pop();
		if (head == NULL)
		{
			head = pRoot;
			pHead = head;
		}
		else
		{
			pHead->right = pRoot;
			pRoot->left = pHead;
			pHead = pRoot;
		}
		pRoot = pRoot->right;
	}

	return head;
}

这道题的关键在于minIndex数组存储的是最小值的下标,存元素就错了

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

class Stack
{
public:
	Stack(int i = -1, int j = -1) : index1(i), index2(j) {}

	void push(int item)
	{
		if (++index1 == size)
			return;

		data[index1] = item;

		if (index2 == -1 || data[minIndex[index2]] > item)
		{
			minIndex[++index2] = index1;
		}
	}

	void pop()
	{
		if (index1 == -1)
			return;

		if (minIndex[index2] == index1)
			--index2;
		--index1;
	}

	int min()
	{
		if (index1 <= -1 || index2 <= -1)
			return -1;

		return data[minIndex[index2]];
	}

	bool empty()
	{
		return index1 == -1;
	}

private:
	static const int size = 20;
	int data[size];
	int minIndex[size];
	int index1;
	int index2;
};

void main()
{
	Stack stack;
	stack.push(3);
	stack.push(2);
	stack.push(5);
	stack.push(1);
	stack.push(4);
	
	while (!stack.empty())
	{
		cout << "minValue: " << stack.min() << endl;
		stack.pop();
	}
}


本题的两种经典解法:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

int array[] = {1, -2, 3, 10, -4, 7, 2, -5};
const int size = sizeof array / sizeof *array;

#define INF 1 << 31

int maxSubarray(int *array, int size)
{
	if (array == NULL || size <= 0)
		return -INF;

	int maxInclude = array[0];
	int maxSum = array[0];

	for (int i = 1; i < size; i++)
	{
		maxInclude = max(maxInclude + array[i], array[i]);
		maxSum = max(maxInclude, maxSum);
	}

	return maxSum;
}

void main()
{
	int result = maxSubarray(array, size);
	if (result == -INF)
		cout << "error" << endl;
	else
		cout << "result = " << result << endl;
}

第二种:

int maxSubarray(int *array, int size)
{
	if (array == NULL || size <= 0)
		return -INF;

	int sum = 0;
	int tempSum = 0;

	for (int i = 0; i < size; i++)
	{
		if (tempSum < 0)
			tempSum = 0;
		tempSum += array[i];
		if (tempSum > sum)
			sum = tempSum;
	}

	return sum;
}

递归解法:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

struct Node  
{  
	Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}  
	int data;  
	Node *left;  
	Node *right;  
};  

Node* construct()  
{    
	Node *node5 = new Node(7);  
	Node *node4 = new Node(4);  
	Node *node3 = new Node(12);  
	Node *node2 = new Node(5, node4, node5);  
	Node *node1 = new Node(10, node2, node3);  

	return node1;  
}

void print(const vector<Node*> &nvec)
{
	for (size_t i = 0; i < nvec.size(); i++)
		cout << nvec[i]->data << " ";
	cout << endl;
	return;
}

void printSumTree(Node *root, vector<Node*> &nvec, int sum)
{
	if (root == NULL)
		return;

	if (root->data == sum && root->left == NULL && root->right == NULL)
	{
		nvec.push_back(root);
		print(nvec);
		nvec.pop_back();
		return;
	}

	nvec.push_back(root);
	printSumTree(root->left, nvec, sum - root->data);
	printSumTree(root->right, nvec, sum - root->data);
	nvec.pop_back();
}

void main()
{
	Node *root = construct();
	vector<Node*> nvec;
	printSumTree(root, nvec, 22);
}

循环解法:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>

using namespace std;

struct Node  
{  
	Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}  
	int data;  
	Node *left;  
	Node *right;  
};  

Node* construct()  
{    
	Node *node5 = new Node(7);  
	Node *node4 = new Node(4);  
	Node *node3 = new Node(12);  
	Node *node2 = new Node(5, node4, node5);  
	Node *node1 = new Node(10, node2, node3);  

	return node1;  
}

void print(const vector<Node*> &nvec)
{
	for (size_t i = 0; i < nvec.size(); i++)
		cout << nvec[i]->data << " ";
	cout << endl;
	return;
}

void printSumTree(Node *root, vector<Node*> &nvec, int sum)
{
	if (root == NULL)
		return;

	stack<Node*> nstack;
	nstack.push(root);
	Node *pRoot = root;
	Node *prev = NULL;

	while (!nstack.empty())
	{
		pRoot = nstack.top();
		if (prev != pRoot->left && prev != pRoot->right)
		{
			if (pRoot->right)
				nstack.push(pRoot->right);
			if (pRoot->left)
				nstack.push(pRoot->left);
		}

		if (prev != pRoot->left && prev != pRoot->right)
		{
			nvec.push_back(pRoot);
			sum -= pRoot->data;
		}
	
		if (pRoot->left == NULL && pRoot->right == NULL)
		{
			if (sum == 0)
				print(nvec);
			nstack.pop();
			sum += nvec[nvec.size() - 1]->data;
			nvec.pop_back();
		}
		if (prev == pRoot->left || prev == pRoot->right)
		{
			nstack.pop();
			sum += nvec[nvec.size() - 1]->data;
			nvec.pop_back();
		}

		prev = pRoot;
	}
}

void main()
{
	Node *root = construct();
	vector<Node*> nvec;
	printSumTree(root, nvec, 22);
}

太经典的题了,解法N种

1. 快排,复杂度O(NlogN) 给出这个算法的基本上面试都被毙掉

2. 最大堆求kmin,复杂度O(Nlogk)这个复杂度就可通过面试了

3. 利用计数排序和快排的partition算法的复杂度为O(N),这样的复杂度完全可以令面试官满意了

这里只给出计数排序和partition的算法:



这么久了,还是没能理解这道题是要写代码,还是。。。



编程之美上的老题了,不带环直接判断尾指针即可

扩展问题:如果有环,题目难度就增大很多了,这个题目在面试50题里我有写到过

关于就相交的第一个节点,遍历几次即可



1. 冷热

2. 1、2、4

3. 链表反转是老题了

    这个不难吧

    整理一个数组,难道是随机化。。。

    字符串匹配,名题百则上有提到

    颠倒一个字符串啊,很easy吧

    3次reverse即可

    字符串匹配问题

    怎么比较,擦

    异或算法

    左移3位、左移3位减1



#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>

using namespace std;

int array[] = {5, 7, 6, 9, 11, 10, 8};
const int size = sizeof array / sizeof *array;

bool isPostOrder(int *array, int start, int end)
{
	if (array == NULL || size <= 0)
		return false;

	if (start > end)
		return false;

	if (start == end || start == end - 1)
		return true;

	int pivot = array[end];
	int i = start;
	int j = end - 1;

	while (i < end - 1 && array[i] < pivot)
		i++;
	while (j >= start && array[j] >= pivot)
		j--;

	return (i > j) && isPostOrder(array, start, j) && isPostOrder(array, i, end - 1);
}

void main()
{
	bool result = isPostOrder(array, 0, size - 1);
	if (result == true)
		cout << "is post order" << endl;
	else
		cout << "not post order" << endl;
}


1. 首先全部翻转

2. 碰见空格反转




#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

struct Node
{
	Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
	int data;
	Node *left;
	Node *right;
};

Node* construct()
{
	Node *node9 = new Node(9);
	Node *node8 = new Node(8);
	Node *node7 = new Node(7);
	Node *node6 = new Node(6, NULL, node9);
	Node *node5 = new Node(5, node8);
	Node *node4 = new Node(4, node6, node7);
	Node *node3 = new Node(3, node5);
	Node *node2 = new Node(2, node3, node4);
	Node *node1 = new Node(1, NULL, node2);

	return node1;
}

struct Result
{
	Result(int i = 0, int j = -1) : dist(i), depth(j) {}
	int dist;
	int depth;
};

Result getMaxDist(Node *root)
{
	if (root == NULL)
		return Result();

	Result result;
	if (root == NULL)
	{
		result.depth = -1;
		result.dist = 0;
		return result;
	}
	Result lResult = getMaxDist(root->left);
	Result rResult = getMaxDist(root->right);
	result.depth = max(lResult.depth, rResult.depth) + 1;
	result.dist = max(max(lResult.dist, rResult.dist), lResult.depth + rResult.depth + 2);

	return result;
}

void main()
{
	Node *root = construct();
	Result result = getMaxDist(root);

	cout << "result.depth = " << result.depth << endl;
	cout << "result.dist = " << result.dist << endl;
}


只推荐两种解法:

一、模板

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

template <int i>
struct Sum
{
	enum Value { N = Sum<i - 1>::N + i };
};

template <>
struct Sum<1>
{
	enum Value { N = 1 };
};

void main()
{
	cout <<  Sum<100>::N << endl;
}

二、构造函数

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

class Sum
{
public:
	Sum()
	{
		n++;
		sum += n;
	}

	static int getSum()
	{
		return sum;
	}

private:
	static int sum;
	static int n;
};

int Sum::sum = 0;
int Sum::n = 0;

void main()
{
	Sum sum[100];
	cout << Sum::getSum() << endl;
}



这个链表题要注意几点:

1. K可能为负数或0

2. K可能大于链表的长度



这道题太easy,而且UT简单


递归和循环的解法都要会~



何时输出endl才是关键

#include <iostream>
#include <queue>

using namespace std;

struct Node 
{
	Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight){}
	int data;
	Node *left;
	Node *right;
};

void printLevel(Node *root)
{
	if (root == NULL)
		return;

	queue<Node *> qnodes;
	qnodes.push(root);

	int indexFast = 1;
	int indexSlow = 1;
	int index = 0;
	while (!qnodes.empty())
	{
		Node *node = qnodes.front();
		qnodes.pop();

		if (node->left)
		{
			indexFast++;
			qnodes.push(node->left);
		}
		if (node->right)
		{
			indexFast++;
			qnodes.push(node->right);
		}

		index++;
		cout << node->data << " ";
		if (index == indexSlow)
		{
			indexSlow = indexFast;
			cout << endl;
		}
	}
}

Node *construct()
{
	Node *node7 = new Node(11);
	Node *node6 = new Node(9);
	Node *node5 = new Node(7);
	Node *node4 = new Node(5);
	Node *node3 = new Node(10, node6, node7);
	Node *node2 = new Node(6, node4, node5);
	Node *node1 = new Node(8, node2, node3);

	return node1;
}

void main()
{
	Node *root = construct();
	printLevel(root);
}




很简单啦~


两种解法:其一、模拟list;其二、利用公式的解法



三种解法:其一、递归;其二、循环;其三、最牛逼的logN复杂度解法



应该考虑一下几点:

1. 输入的字符串中有非数字

2. 输入的字符串中有+-符号

3. 输入的字符串过长所产生的溢出问题



#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

void printCombine(int n, int m, int index, bool *flag)
{
	if (m < 0 || index == n)
		return;

	if (m == 0)
	{
		for (int i = 0; i < n; i++)
		{
			if (flag[i] == true)
				cout << i + 1 << " ";
		}
		cout << endl;
		return;
	}

	flag[index] = true;
	printCombine(n, m - index - 1, index + 1, flag);
	flag[index] = false;
	printCombine(n, m, index + 1, flag);
}

void main()
{
	cout << "input two numbers" << endl;
	int m, n;
	cin >> m >> n;

	bool *flags = new bool[n];
	if (flags == NULL)
		return;

	for (int i = 0; i < n; i++)
		flags[i] = false;

	printCombine(n, m, 0, flags);

	delete[] flags;
}






这道题写过很多遍了~



简单题



3次reverse



Fibonacci数列问题



经典题







BFS




把百度那道珠子的题搞定,编程之美上最短摘要的生成一模一样



这道题和编程之美上的信号量那道题一回事



编程之美上已经说得很详细了,这道题将会作为一道专题写进blog里















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值