剑指offer之面试题3
#include <iostream>
using namespace std;
const int rowSize = 4;
const int colSize = 4;
int array[rowSize][colSize] = {
1, 2, 8, 9,
2, 3, 9, 12,
4, 7, 10, 13,
6, 8, 11, 15
};
struct Position
{
int xPos;
int yPos;
};
bool searchArray(int array[][colSize], int destValue, Position &postion)
{
if (array == NULL)
return false;
for (int i = 0; i < rowSize; i++)
{
if (array[i] == NULL)
return false;
}
bool flag = false;
for (int row = 0, col = colSize - 1; row < rowSize && col >= 0;)
{
if (array[row][col] > destValue)
{
col--;
}
else if (array[row][col] < destValue)
{
row++;
}
else
{
postion.xPos = row + 1;
postion.yPos = col + 1;
flag = true;
break;
}
}
return flag;
}
void print(int array[][colSize])
{
for (int i = 0; i < rowSize; i++)
{
for (int j = 0; j < colSize; j++)
{
cout << array[i][j] << " ";
}
cout << endl;
}
}
void main()
{
print(array);
Position position;
for (int i = 1; i <= 16; i++)
{
bool flag = searchArray(array, i, position);
if (flag == true)
cout << "find " << i << " at: " << "(" << position.xPos << ", " << position.yPos << ")" << endl;
else
cout << "can't find " << i << endl;
}
}
面试题4:替换空格
#include <iostream>
using namespace std;
void replace(char *source, const char *str = "%20")
{
if (source == NULL || str == NULL)
return;
const int length = strlen(source);
int count = 0;
for (int i = 0; i < length; i++)
{
if (source[i] == ' ')
count++;
}
if (count == 0)
return;
const int strLen = strlen(str);
if (strLen == 0)
{
cout << "本题不考虑这个情形" << endl;
return;
}
const int destLength = length + (strLen - 1) * count;
source[destLength] = '\0';
int destPos = destLength - 1;
for (int i = length - 1; i >= 0; i--)
{
if (source[i] == ' ')
{
for (int j = strLen - 1; j >= 0; j--)
{
source[destPos--] = str[j];
}
}
else
{
source[destPos--] = source[i];
}
}
}
void main()
{
const int size = 100;
char source[size] = " We are happy ";
replace(source);
cout << "after replace: " << endl;
cout << "source: " << source << endl;
}
面试题5:从尾到头打印链表
#include <iostream>
#include <stack>
using namespace std;
struct Node
{
Node(int i = 0, Node *next = NULL) : next(next), data(i) {}
Node *next;
int data;
};
void printLink(Node *head, bool flag, const char *str = "recurse")
{
if (head == NULL)
return;
static bool myFlag = false;
if (!myFlag)
{
cout << str << endl;
myFlag = true;
}
printLink(head->next, flag, str);
cout << head->data << " ";
}
void printLink(Node *head, const char *str = "iterator")
{
if (head == NULL)
return;
static bool myFlag = false;
if (!myFlag)
{
cout << str << endl;
myFlag = true;
}
stack<Node *> snode;
while (head != NULL)
{
snode.push(head);
head = head->next;
}
while (!snode.empty())
{
Node *node = snode.top();
cout << node->data << " ";
snode.pop();
}
}
Node *construct()
{
Node *head = NULL;
Node *pHead = head;
for (int i = 1; i <= 10; i++)
{
Node *node = new Node(i);
if (head == NULL)
{
head = node;
pHead = head;
}
else
{
pHead->next = node;
pHead = pHead->next;
}
}
return head;
}
void main()
{
Node *head = construct();
printLink(head, true);
cout << endl;
printLink(head);
}
面试题6:重建二叉树
#include <iostream>
#include <vector>
using namespace std;
struct Node
{
Node(int i = 0, Node *left = NULL, Node *right = NULL) : m_pLeft(left), m_pRight(right), data(i) {}
Node *m_pLeft;
Node *m_pRight;
char data;
};
const char *preOrder = "12473568";
const char *inOrder = "47215386";
const int len = strlen(preOrder);
Node *constructTree(const char *preOrder, const char *inOrder, int inLen)
{
if (preOrder == NULL || inOrder == NULL || inLen == 0)
return NULL;
Node *node = new Node(*preOrder);
int pos = 0;
while (inOrder[pos] != *preOrder)
pos++;
if (pos == inLen)
{
cerr << "wrong input" << endl;
return NULL;
}
node->m_pLeft = constructTree(preOrder + 1, inOrder, pos);
node->m_pRight = constructTree(preOrder + pos + 1, inOrder + pos + 1, inLen - pos - 1);
return node;
}
void printLevel(Node *root)
{
if (root == NULL)
return;
vector<Node *> nvec;
nvec.push_back(root);
int start = 0;
int end = 1;
int pos = end;
while (start != end)
{
Node *node = nvec[start];
cout << node->data << " ";
start++;
if (node->m_pLeft)
{
nvec.push_back(node->m_pLeft);
end++;
}
if (node->m_pRight)
{
nvec.push_back(node->m_pRight);
end++;
}
if (start == pos)
{
pos = end;
cout << endl;
}
}
}
void PreOrder(Node *root)
{
if (root)
{
cout << root->data << " ";
PreOrder(root->m_pLeft);
PreOrder(root->m_pRight);
}
}
void InOrder(Node *root)
{
if (root)
{
InOrder(root->m_pLeft);
cout << root->data << " ";
InOrder(root->m_pRight);
}
}
void main()
{
Node *root = constructTree(preOrder, inOrder, strlen(inOrder));
if (root == NULL)
{
cerr << "construct failed" << endl;
}
else
{
printLevel(root);
PreOrder(root);
cout << endl;
InOrder(root);
}
}
面试题7:用两个栈来实现队列
#include <iostream>
#include <stack>
using namespace std;
class MyQueue
{
public:
void add(int i)
{
istack2.push(i);
}
void del()
{
if (istack1.empty())
{
if (istack2.empty())
{
cout << "empty queue" << endl;
return;
}
while (!istack2.empty())
{
int data = istack2.top();
istack1.push(data);
istack2.pop();
}
}
istack1.pop();
}
int front()
{
if (istack1.empty())
{
if (istack2.empty())
{
cout << "empty queue" << endl;
return -1;
}
while (!istack2.empty())
{
int data = istack2.top();
istack1.push(data);
istack2.pop();
}
}
return istack1.top();
}
bool empty()
{
if (istack1.empty() && istack2.empty())
return true;
else
return false;
}
private:
stack<int> istack1;
stack<int> istack2;
};
void main()
{
MyQueue myQueue;
for (int i = 1; i <= 5; i++)
{
myQueue.add(i);
}
while (!myQueue.empty())
{
cout << myQueue.front() << endl;
myQueue.del();
}
}
面试题8:求旋转数组的最小值
#include <iostream>
using namespace std;
const int array[] = {7, 8, 9, 10, 1, 2, 3, 4, 5, 6};
const int size = sizeof array / sizeof *array;
int findMinValue(const int *array, int left, int right)
{
if (array == NULL || left < 0 || left > right || right < 0)
return -1;
if (left == right)
return array[left];
int mid = left + (right - left) / 2;
if (mid == left)
return min(array[left], array[right]);
int minValue;
while (left != right - 1)
{
mid = left + (right - left) / 2;
if (array[left] == array[mid] && array[mid] == array[right])
{
minValue = array[left];
for (int i = left + 1; i <= right; i++)
{
if (array[i] < minValue)
minValue = array[i];
}
return minValue;
}
if (array[mid] < array[right])
right = mid;
else if (array[mid] > array[left])
left = mid;
}
minValue = min(array[left], array[right]);
return minValue;
}
void main()
{
int value = findMinValue(array, 0, size - 1);
cout << "value: " << value << endl;
}
#include <iostream>
using namespace std;
int array[] = {1};
const int size = sizeof array / sizeof *array;
int getMinNumber(int *array, int size)
{
if (array == NULL || size <= 0)
return -1;
int leftIndex = 0;
int rightIndex = size - 1;
while (leftIndex != rightIndex - 1)
{
int mid = (rightIndex - leftIndex) / 2 + leftIndex;
if (array[leftIndex] == array[mid] && array[mid] == array[rightIndex])
{
int minValue = array[leftIndex];
for (int i = leftIndex + 1; i <= rightIndex; i++)
{
if (array[i] < minValue)
minValue = array[i];
}
return minValue;
}
if (array[leftIndex] < array[rightIndex])
{
return array[leftIndex];
}
if (array[mid] > array[leftIndex])
leftIndex = mid;
else
rightIndex = mid;
}
return array[rightIndex];
}
void main()
{
int ret = getMinNumber(array, size);
cout << "ret = " << ret << endl;
}
面试题9:斐波那契数列
三种方法:递归、循环和log(N)级解
题目简单,不写
面试题10:求十进制中1的个数
int getNumberOne1(int number)
{
int count = 0;
while (number)
{
count++;
number = number & (number - 1);
}
return count;
}
int getNumberOne2(int number)
{
int count = 0;
while (number)
{
if (number & 0x01)
count++;
number = number >> 1;
}
return count;
}
int getNumberOne3(long long int n)
{
int count = 0;
unsigned int flag = 1;
while (flag)
{
if (n & flag)
count++;
flag = flag << 1;
}
return count;
}
书中给出3种解法,解法2存在负数时变死循环
关于负数的二进制说明:
比如-1的二进制,首先是1, 00000000 00000000 00000000 00000001,补码:11111111 11111111 11111111 11111110,然后+1,得11111111 11111111 11111111 11111111,共计32个1
关于解法3,很奇怪的地方是居然能退出循环。。。不可思议!!!如果直接flag = flag << 32,flag的值却是1。。。oh, no!!! %>_<%
面试题11:数值的整数次方
#include <iostream>
using namespace std;
bool equalZero(double number)
{
if (number < 0.000001 && number > -0.000001)
return true;
else
return false;
}
double _myPow(double base, int exp)
{
if (exp == 0)
return 1;
if (exp == 1)
return base;
double result = _myPow(base, exp >> 1);
result *= result;
if (exp & 0x01)
result *= base;
return result;
}
double _myPow2(double base, int exp)
{
if (exp == 0)
return 1;
double result = 1;
while (exp)
{
if (exp & 0x01)
result *= base;
base *= base;
exp = exp >> 1;
}
return result;
}
double myPow(double base, int exp)
{
if (equalZero(base))
return 0;
if (exp == 0)
return 1;
bool flag = false;
if (exp < 0)
{
flag = true;
exp = -exp;
}
double result = _myPow2(base, exp);
if (flag)
{
result = 1 / result;
}
return result;
}
void main()
{
double base = -2.0;
int exp = -5;
double result = myPow(base, exp);
cout << "result: " << result << endl;
}
面试题12:打印1到最大的N位数
#include <iostream>
using namespace std;
const int size = 10;
char array[size];
void printNumber(int number)
{
int i;
for (i = 0; i < number; i++)
{
if (array[i] != '0')
break;
}
if (i == number)
return;
for (int j = i; j < number; j++)
{
cout << array[j];
}
cout << endl;
}
void printNumber2(int number)
{
int i;
for (i = 1; i <= number; i++)
{
if (array[i] != '0')
break;
}
if (i == number + 1)
return;
for (int j = i; j <= number; j++)
{
cout << array[j];
}
cout << endl;
}
void recursePrint(int number, int index)
{
if (index == number)
{
printNumber(number);
return;
}
for (int i = 0; i < 10; i++)
{
array[index] = i + '0';
recursePrint(number, index + 1);
}
}
void iteratorPrint(int number)
{
array[number + 1] = '\0';
bool flag = false;
while (true)
{
if (array[0] == '1')
break;
for (int i = number; i >= 0; i--)
{
if (i == number)
{
if (array[i] == '9')
{
array[i] = '0';
flag = true;
}
else
{
array[i]++;
break;
}
}
else
{
if (flag)
{
if (array[i] == '9')
{
array[i] = '0';
flag = true;
}
else
{
array[i]++;
flag = false;
break;
}
}
}
}
printNumber2(number);
}
}
void main()
{
memset(array, '0', size);
iteratorPrint(3);
}
面试题13:在O(1)时间删除链表结点
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *p = NULL) : data(i), next(p) {}
Node *next;
int data;
};
Node *construct(Node *&pNode)
{
Node *head = NULL;
Node *pHead = head;
for (int i = 1; i <= 10; i++)
{
Node *node = new Node(i);
if (i == 10)
pNode = node;
if (head == NULL)
{
head = node;
pHead = head;
}
else
{
pHead->next = node;
pHead = pHead->next;
}
}
return head;
}
void deleteNode(Node *&head, Node *destNode)
{
if (head == NULL || destNode == NULL)
return;
if (head == destNode)
{
head = head->next;
delete destNode;
return;
}
if (destNode->next == NULL)
{
Node *pHead = head;
while (pHead->next != destNode)
pHead = pHead->next;
pHead->next = NULL;
delete destNode;
return;
}
else
{
Node *destNodeNext = destNode->next;
destNode->data = destNodeNext->data;
destNode->next = destNodeNext->next;
delete destNodeNext;
}
}
void printLink(Node *head)
{
if (head == NULL)
return;
while (head != NULL)
{
cout << head->data << " ";
head = head->next;
}
}
void main()
{
Node *pNode = NULL;
Node *head = construct(pNode);
cout << "before delete: " << endl;
printLink(head);
deleteNode(head, pNode);
cout << endl << "after delete: " << endl;
printLink(head);
}
面试题14:调整数组顺序使奇数位于偶数前面
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int size = sizeof array / sizeof *array;
void tranverse(int *array, int size)
{
if (array == NULL || size <= 0)
return;
int i = 0;
int j = size - 1;
while(true)
{
while (array[i] & 0x01)
i++;
while (!(array[j] & 0x01))
j--;
if (i > j)
break;
swap(array[i], array[j]);
}
}
void main()
{
tranverse(array, size);
copy(array, array + size, ostream_iterator<int>(cout, " "));
}
面试题15:链表中倒数第k个结点
本题注意点:1
1. 关于k的取值范围的判定
2. 如果链表长度恰好等于k时的处理
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *p = NULL) : data(i), next(p) {}
Node *next;
int data;
};
Node *construct(Node *pNode)
{
Node *head = NULL;
Node *pHead = head;
for (int i = 1; i <= 10; i++)
{
Node *node = new Node(i);
if (i == 10)
pNode = node;
if (head == NULL)
{
head = node;
pHead = head;
}
else
{
pHead->next = node;
pHead = pHead->next;
}
}
return head;
}
Node* findLastKNode(Node *head, int k)
{
if (head == NULL || k <= 0)
return NULL;
Node *fastNode = head;
Node *slowNode = head;
while (fastNode != NULL && k != 0)
{
fastNode = fastNode->next;
k--;
}
if (fastNode == NULL && k != 0)
{
cout << "k is too big" << endl;
return NULL;
}
while (fastNode != NULL)
{
fastNode = fastNode->next;
slowNode = slowNode->next;
}
return slowNode;
}
void printLink(Node *head)
{
if (head == NULL)
return;
while (head != NULL)
{
cout << head->data << " ";
head = head->next;
}
}
void main()
{
Node *head = construct(NULL);
for (int i = 1; i <= 10; i++)
{
Node *node = findLastKNode(head, i);
if (node)
cout << "last " << i << " node: " << node->data << endl;
}
}
面试题16:反转链表
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *p = NULL) : data(i), next(p) {}
Node *next;
int data;
};
Node *construct(Node *pNode)
{
Node *head = NULL;
Node *pHead = head;
for (int i = 1; i <= 10; i++)
{
Node *node = new Node(i);
if (i == 10)
pNode = node;
if (head == NULL)
{
head = node;
pHead = head;
}
else
{
pHead->next = node;
pHead = pHead->next;
}
}
return head;
}
Node *recursiveReverse(Node *head, Node *&newHead)
{
if (head ->next == NULL)
return head;
Node *node = recursiveReverse(head->next, newHead);
if (newHead == NULL)
{
newHead = node;
node->next = head;
node = head;
node->next = NULL;
}
else
{
node->next = head;
node = head;
node->next = NULL;
}
return node;
}
Node *reverseLink(Node *head)
{
if (head == NULL || head->next == NULL)
return head;
Node *pHead = head;
Node *pHeadNext = head->next;
Node dump;
while (pHeadNext != NULL)
{
head->next = dump.next;
dump.next = head;
head = pHeadNext;
pHeadNext = pHeadNext->next;
}
head->next = dump.next;
dump.next = head;
head = pHeadNext;
return dump.next;
}
Node* reverse(Node *head)
{
if(head == NULL) {
cout << "link is null" << endl;
return NULL;
}
Node *newHead = NULL, *pHeadNext = head;
while(pHeadNext) {
head = pHeadNext;
pHeadNext = pHeadNext->next;
head->next = newHead;
newHead = head;
}
return newHead;
}
void printLink(Node *head)
{
if (head == NULL)
return;
while (head != NULL)
{
cout << head->data << " ";
head = head->next;
}
}
void main()
{
Node *head = construct(NULL);
Node *pHead = NULL;
recursiveReverse(head, pHead);
printLink(pHead);
Node *newHead = reverseLink(pHead);
cout << endl;
printLink(newHead);
cout << endl;
Node *newHead2 = reverse(newHead);
printLink(newHead2);
}
递归算法:
Node* recursiveReverse(Node *PreNode, Node *CurrentNode)
{
Node* resultNode;
if(CurrentNode == NULL)
return NULL;
if(CurrentNode->next == NULL)
{
CurrentNode->next = PreNode;
resultNode = CurrentNode;
}
else
{
resultNode = recursiveReverse(CurrentNode, CurrentNode->next);
CurrentNode->next = PreNode;
}
PreNode->next = NULL;
return resultNode;
}
╮(╯▽╰)╭一天才做了这几道,哭啊。。。伤心。。。
面试题17:合并两个排序链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
链表1: 1 3 5 7
链表2: 2 4 6 8
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *pNext = NULL) : data(i), next(pNext) {}
int data;
Node *next;
};
Node *construct()
{
Node *node4 = new Node(7);
Node *node3 = new Node(5, node4);
Node *node2 = new Node(3, node3);
Node *node1 = new Node(1, node2);
return node1;
}
Node* construct2()
{
Node *node4 = new Node(8);
Node *node3 = new Node(6, node4);
Node *node2 = new Node(4, node3);
Node *node1 = new Node(2, node2);
return node1;
}
Node* mergeLink(Node *head1, Node *head2)
{
if (head1 == NULL || head2 == NULL)
return NULL;
Node *pHead1 = head1;
Node *pHead2 = head2;
Node *head = NULL;
Node *pHead = head;
while (pHead1 != NULL && pHead2 != NULL)
{
if (head == NULL)
{
if (pHead1->data < pHead2->data)
{
head = pHead1;
pHead1 = pHead1->next;
pHead = head;
}
else
{
head = pHead2;
pHead2 = pHead2->next;
pHead = head;
}
}
else
{
if (pHead1->data < pHead2->data)
{
pHead->next = pHead1;
pHead1 = pHead1->next;
pHead = pHead->next;
}
else
{
pHead->next = pHead2;
pHead2 = pHead2->next;
pHead = pHead->next;
}
}
}
if (pHead1 == NULL)
pHead->next = pHead2;
else
pHead->next = pHead1;
return head;
}
void printLink(Node *head)
{
if (head == NULL)
return;
Node *pHead = head;
while (pHead != NULL)
{
cout << pHead->data << " ";
pHead = pHead->next;
}
return;
}
void main()
{
Node *head1 = construct();
Node *head2 = construct2();
cout << "two LINK: " << endl;
printLink(head1);
cout << endl;
printLink(head2);
cout << endl;
Node *newHead = mergeLink(head1, head2);
cout << "after merge: " << endl;
printLink(newHead);
}
这道题目很弱,但是书上给出的解法很NB
Node *recursiveMergeLink(Node *head1, Node *head2)
{
if (head1 == NULL)
return head2;
else if (head2 == NULL)
return head1;
Node *head;
if (head1->data < head2->data)
{
head = head1;
head->next = recursiveMergeLink(head1->next, head2);
}
else
{
head = head2;
head->next = recursiveMergeLink(head1, head2->next);
}
return head;
}
面试题18:树的子结构
题目:输入两颗二叉树A和B,判断B是不是A的子结构。
8
8 7
9 2
4 7
8
9 2
#include <iostream>
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(7);
Node *node6 = new Node(4);
Node *node5 = new Node(2, node6, node7);
Node *node4 = new Node(9);
Node *node3 = new Node(7);
Node *node2 = new Node(8, node4, node5);
Node *node1 = new Node(8, node2, node3);
return node1;
}
Node* construct2()
{
Node *node3 = new Node(2);
Node *node2 = new Node(9);
Node *node1 = new Node(8);
return node1;
}
bool hasSubTree(Node *root1, Node *root2)
{
if (root2 == NULL)
return true;
if (root1 == NULL)
return false;
if (root1->data != root2->data)
return false;
else
return hasSubTree(root1->left, root2->left) && hasSubTree(root1->right, root2->right);
}
bool isSubTree(Node *root1, Node *root2)
{
if (root1 == NULL || root2 == NULL)
return false;
bool flag = false;
flag = hasSubTree(root1, root2);
bool leftFlag = false;
bool rightFlag = false;
if (root1->left)
leftFlag = isSubTree(root1->left, root2);
if (root1->right)
rightFlag = isSubTree(root1->right, root2);
return flag || leftFlag || rightFlag;
}
void main()
{
Node *root1 = construct();
Node *root2 = construct2();
bool result = isSubTree(root1, root2);
if (result == true)
cout << "has subtree" << endl;
else
cout << "no sub tree" << endl;
}
递归的方法很简单,那么关于迭代的方法呢。。。
#include <iostream>
#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 *node7 = new Node(7);
Node *node6 = new Node(4);
Node *node5 = new Node(2, node6, node7);
Node *node4 = new Node(9);
Node *node3 = new Node(7);
Node *node2 = new Node(8, node4, node5);
Node *node1 = new Node(8, node2, node3);
return node1;
}
Node* construct2()
{
Node *node3 = new Node(2);
Node *node2 = new Node(9);
Node *node1 = new Node(8, node2, node3);
return node1;
}
bool checkSubTree(Node *root1, Node *root2)
{
if (root1 == NULL || root2 == NULL)
return false;
stack<Node *> nstack1;
stack<Node *> nstack2;
bool result = true;
while (!nstack2.empty() || root2 != NULL)
{
if (root2 != NULL)
{
if (root1->data == root2->data)
{
nstack1.push(root1);
nstack2.push(root2);
root1 = root1->left;
root2 = root2->left;
}
else
{
result = false;
break;
}
}
else
{
root1 = nstack1.top();
root2 = nstack2.top();
nstack1.pop();
nstack2.pop();
root1 = root1->right;
root2 = root2->right;
}
}
return result;
}
bool isSubTree(Node *root1, Node *root2)
{
if (root1 == NULL || root2 == NULL)
return false;
stack<Node*> nstack;
bool result = false;
while (!nstack.empty() || root1 != NULL)
{
if (root1 != NULL)
{
if (checkSubTree(root1, root2) == true)
{
result = true;
break;
}
nstack.push(root1);
root1 = root1->left;
}
else
{
root1 = nstack.top();
nstack.pop();
root1 = root1->right;
}
}
return result;
}
void main()
{
Node *root1 = construct();
Node *root2 = construct2();
if (isSubTree(root1, root2) == true)
cout << "is subtree" << endl;
else
cout << "not a subtree" << endl;
}
面试题19:二叉树的镜像
题目:请完成一个函数,输入一棵二叉树,该函数输出它的镜像
8
6 10
5 7 9 11
#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;
};
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);
Node *node2 = new Node(6, node4, node5);
Node *node1 = new Node(8, node2, node3);
return node1;
}
void printLevel(Node *root)
{
if (root == NULL)
return;
queue<Node *> qnode;
qnode.push(root);
int count = 1;
int start = 0;
int tempCount = 0;
while (!qnode.empty())
{
tempCount = 0;
while (start != count)
{
Node *top = qnode.front();
if (top != NULL)
{
if (top->left)
{
qnode.push(top->left);
tempCount++;
}
else if (top->left == NULL && top->right != NULL)
{
qnode.push(NULL);
tempCount++;
}
if (top->right)
{
qnode.push(top->right);
tempCount++;
}
else if (top->left != NULL && top->right == NULL)
{
qnode.push(NULL);
tempCount++;
}
}
start++;
if (top != NULL)
cout << top->data;
else
cout << " ";
qnode.pop();
}
count = tempCount;
start = 0;
cout << endl;
}
}
Node* swapTree(Node *root)
{
if (root == NULL)
return root;
swap(root->left, root->right);
swapTree(root->left);
swapTree(root->right);
return root;
}
void main()
{
Node *root = construct();
printLevel(root);
Node* root2 = swapTree(root);
printLevel(root2);
}
面试题20:顺时针打印矩阵
输入矩阵如下:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
输出:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
using namespace std;
const int size = 4;
int array[4][4] =
{
1, 2, 3, 4,
12, 13, 14, 5,
11, 16, 15, 6,
10, 9, 8, 7
};
void print(int (*array)[size])
{
for (int i = 0; i < (size + 1) / 2; i++)
{
for (int j = i; j < size - i; j++)
cout << array[i][j] << " ";
for (int j = i + 1; j < size - i; j++)
cout << array[j][size - i - 1] << " ";
for (int j = size - i - 2; j >= i; j--)
cout << array[size - i - 1][j] << " ";
for (int j = size - i - 2; j >= i + 1; j--)
cout << array[j][i] << " ";
}
}
void main()
{
print(array);
}
递归解法:
#include <iostream>
using namespace std;
const int size = 16;
int array[size] =
{
1, 2, 3, 4,
12, 13, 14, 5,
11, 16, 15, 6,
10, 9, 8, 7
};
void print(int *array, int rows, int cols, int index)
{
if (array == NULL || rows < 0 || cols < 0 || index >= min(rows >> 1, cols >> 1))
return;
for (int i = index; i < cols - index; i++)
cout << array[index * rows + i] << " ";
for (int i = index + 1; i < rows - index; i++)
cout << array[i * rows + cols - index - 1] << " ";
for (int i = cols - index - 2; i >= index; i--)
cout << array[(rows - index - 1) * rows + i] << " ";
for (int i = rows - index - 2; i > index; i--)
cout << array[i * rows + index] << " ";
print(array, rows, cols, index + 1);
}
void main()
{
print(array, 4, 4, 0);
}
面试题21:包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,在该栈中,调用min,push及pop的时间复杂度都是O(1)
本题目一定要注意,保存的是最小元素的index,而不是最小元素,因为stack里面保存的不一定是int型,有可能是类
#include <iostream>
using namespace std;
class MyStack
{
public:
MyStack(int i = -1, int j = -1) : currentIndex(i), currentIndexMin(j) {}
void push(int item)
{
if (currentIndex == size - 1)
{
cerr << "over flow" << endl;
return;
}
data[++currentIndex] = item;
if (currentIndexMin == -1)
minIndex[++currentIndexMin] = currentIndex;
else if (item < data[minIndex[currentIndexMin]])
{
minIndex[++currentIndexMin] = currentIndex;
}
}
void pop()
{
if (currentIndex == -1)
{
cerr << "under flow" << endl;
return;
}
if (currentIndex == minIndex[currentIndexMin])
{
currentIndexMin--;
}
currentIndex--;
}
int min()
{
if (currentIndexMin == -1)
{
cerr << "under flow" << endl;
return -1;
}
return data[minIndex[currentIndexMin]];
}
private:
static const int size = 100;
int data[size];
int currentIndex;
int currentIndexMin;
int minIndex[size];
};
void main()
{
MyStack myStack;
myStack.push(3);
myStack.push(5);
myStack.push(1);
myStack.push(2);
myStack.push(4);
cout << myStack.min() << endl;
myStack.pop();
cout << myStack.min() << endl;
myStack.pop();
cout << myStack.min() << endl;
myStack.pop();
cout << myStack.min() << endl;
myStack.pop();
cout << myStack.min() << endl;
myStack.pop();
}
面试题22:栈的压入、弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该栈序列对应的一个弹出序列,但是4、3、5、1、2就不可能是该压栈序列的弹出序列。
#include <iostream>
#include <stack>
using namespace std;
int source[] = {1, 2, 3, 4, 5};
int dest[] = {4, 3, 2, 1, 5};
const int size = sizeof source / sizeof *source;
bool isPopSequence(int *source, int sizeSource, int *dest, int sizeDest)
{
if (source == NULL || dest == NULL || sizeSource != sizeDest)
return false;
stack<int> istack;
int indexDest = 0;
int indexSource = 0;
bool flag = false;
while (indexSource != sizeSource && indexDest != sizeDest)
{
istack.push(source[indexSource]);
indexSource++;
while (!istack.empty() && istack.top() == dest[indexDest])
{
istack.pop();
indexDest++;
}
}
if (indexSource == sizeSource && indexDest == sizeDest)
flag = true;
return flag;
}
void main()
{
bool result = isPopSequence(source, size, dest, size);
if (result)
cout << "pos sequence" << endl;
else
cout << "not a pop sequence" << endl;
}
面试题23:从上往下打印二叉树
题目:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。
8
6 10
5 7 9 11
#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);
}
面试题24:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果,如果是返回true,否则返回false,假设输入数组的任意两个数字都互不相同。
比如{5, 7, 6, 9, 11, 10, 8} 则返回true
{7, 4, 6, 5}返回false
#include <iostream>
using namespace std;
//int array[] = {5, 7, 6, 9, 11, 10, 8};
int array[] = {6, 8, 7, 4, 1, 5};
//int array[] = {3, 5};
const int size = sizeof array / sizeof *array;
bool _isPostOrder(int *array, int start, int end)
{
if (start == end)
return true;
int index = end - 1;
while (index >= 0 && array[index] > array[end])
index--;
for (int i = index - 1; i >= start; i--) {
if (array[i] > array[end]) {
cout << array[i] << "is bigger than " << array[index] << endl;
return false;
}
}
if (index == -1) {
cout << "start = " << start << "\t" << "end = " << end << endl;
return _isPostOrder(array, start, end - 1);
}
else
return _isPostOrder(array, start, index) && _isPostOrder(array, index + 1, end - 1);
}
bool isPostOrder(int *array, int size)
{
if (array == NULL || size <= 0)
return false;
return _isPostOrder(array, 0, size - 1);
}
void main()
{
bool result = isPostOrder(array, size);
if (result)
cout << "post order" << endl;
else
cout << "not post order" << endl;
}
UT:
1. 空指针
2. 含有一个元素 {1}
3. 只有左子树 {2, 4, 3, 5} {1, 2, 3, 4}
4. 只有右子树 {6, 8, 7, 5} {4, 3, 2, 1}
5. 左右子树均有
面试题25:二叉树中和为某一值的路径
题目:输入一棵二叉树和一个整数,打印二叉树中结点值的和为输入整数的所有路径,从树的根节点开始往下一直到叶结点所经过的结点形成一条路径。
10
5 12
4 7
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
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(-1);
Node *node4 = new Node(4);
Node *node3 = new Node(12);
Node *node2 = new Node(13, node4, node5);
Node *node1 = new Node(10, node2, node3);
return node1;
}
void printSum(Node *root, int sum, vector<Node *> nvec)
{
if (root == NULL)
return;
nvec.push_back(root);
if (root ->left == NULL && root->right == NULL)
{
if (sum == root->data)
{
for (vector<Node *>::iterator iter = nvec.begin(); iter != nvec.end(); ++iter)
cout << (*iter)->data << " ";
cout << endl;
}
nvec.pop_back();
return;
}
printSum(root->left, sum - root->data, nvec);
printSum(root->right, sum - root->data, nvec);
nvec.pop_back();
}
void main()
{
Node *root = construct();
vector<Node *> nvec;
printSum(root, 22, nvec);
}
面试题26:复杂链表的复制
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *nextNode = NULL, Node *nextRandNode = NULL) : data(i), next(nextNode), randNext(nextRandNode) {}
int data;
Node *next;
Node *randNext;
};
Node *construct()
{
Node *node5 = new Node(5);
Node *node4 = new Node(4, node5);
Node *node3 = new Node(3, node4);
Node *node2 = new Node(2, node3);
Node *node1 = new Node(1, node2);
node5->randNext = node1;
node4->randNext = node2;
node2->randNext = node5;
node1->randNext = node3;
return node1;
}
Node* copyLinkStepOne(Node *head)
{
if (head == NULL)
return head;
Node *pHead = head;
while (pHead != NULL)
{
Node *cloneNode = new Node(pHead->data);
cloneNode->next = pHead->next;
pHead->next = cloneNode;
pHead = cloneNode->next;
}
return head;
}
Node *copyLinkStepTwo(Node *head)
{
if (head == NULL)
return head;
Node *pHead = head;
Node *pCloneHead = pHead->next;
while (pHead != NULL)
{
pCloneHead->randNext = pHead->randNext;
pHead = pCloneHead->next;
if (pHead != NULL)
pCloneHead = pHead->next;
}
return head;
}
Node *copyLinkStepThree(Node *head)
{
if (head == NULL)
return head;
Node *pHead = head;
Node *cloneHead = pHead->next;
Node *pCloneHead = cloneHead;
while (pHead != NULL)
{
pHead->next = pCloneHead->next;
pHead = pCloneHead->next;
if (pHead != NULL)
{
pCloneHead->next = pHead->next;
pCloneHead = pCloneHead->next;
}
else
{
pCloneHead->next = NULL;
}
}
return cloneHead;
}
void printLink(Node *head)
{
if (head == NULL)
return;
cout << head->data << '\t';
if (head->randNext != NULL)
cout << head->randNext->data << endl;
else
cout << endl;
printLink(head->next);
}
void printLink2(Node *head)
{
if (head == NULL)
return;
Node *pHead = head;
while (pHead != NULL)
{
cout << pHead->data << '\t';
if (pHead->randNext != NULL)
cout << pHead->randNext->data << endl;
else
cout << endl;
pHead = pHead->next;
}
}
void main()
{
Node *head = construct();
cout << "source link: " << endl;
printLink(head);
Node *tempCloneHead = copyLinkStepOne(head);
tempCloneHead = copyLinkStepTwo(tempCloneHead);
Node *cloneHead = copyLinkStepThree(tempCloneHead);
cout << "After Copy!!!: Source Link" << endl;
printLink(head);
cout << "After Copy!!!: Clone Link" << endl;
printLink(cloneHead);
}
UT:
1. NULL指针
2. 只有1个node
3. 普通链表
4. 正常的复杂链表
面试题27:二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,要求不能创建任何新的结点,只能调整树中结点指针的指向。
10
6 14
4 8 12 16
输出:4 6 8 10 12 14 16
#include <iostream>
#include <stack>
using namespace std;
struct Node
{
Node(int i = 0, Node *nextNode = NULL, Node *nextRandNode = NULL) : data(i), left(nextNode), right(nextRandNode) {}
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* convert2LinkRecursive(Node *root)
{
if (root == NULL)
return root;
static Node *head = NULL;
static Node *pHead = head;
convert2LinkRecursive(root->left);
if (head == NULL)
{
head = root;
pHead = head;
}
else
{
pHead->right = root;
root->left = pHead;
pHead = root;
}
convert2LinkRecursive(root->right);
return head;
}
Node* convert2LinkIterator(Node *root)
{
if (root == NULL)
return root;
Node *head = NULL;
Node *pHead = head;
stack<Node *> snode;
while (root != NULL || !snode.empty())
{
while (root != NULL)
{
snode.push(root);
root = root->left;
}
root = snode.top();
if (head == NULL)
{
head = root;
pHead = head;
}
else
{
pHead->right = root;
root->left = pHead;
pHead = root;
}
root = root->right;
snode.pop();
}
return head;
}
void printLink(Node *head)
{
if (head == NULL)
return;
cout << head->data << " ";
printLink(head->right);
}
void printLinkLeft(Node *head)
{
if (head == NULL)
return;
Node *pHead = head;
while (pHead->right != NULL)
{
pHead = pHead->right;
}
while (pHead != head)
{
cout << pHead->data << " ";
pHead = pHead->left;
}
cout << pHead->data << endl;
}
void inorder(Node *root)
{
if (root)
{
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
}
void main()
{
Node *root = construct();
inorder(root);
cout << endl;
Node *head = convert2LinkIterator(root);
printLink(head);
cout << endl;
printLinkLeft(head);
}
面试题28:字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列,例如输入字符串abc,则打印出字符串a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和aba。
#include <iostream>
#include <vector>
using namespace std;
char str[] = {'a', 'b', 'c'};
const int size = sizeof str / sizeof *str;
void printCombine2(char *str, int index, int size)
{
if (str == NULL || index < 0 || size <= 0 || index > size)
return;
if (index == size)
cout << str << endl;
for (int i = index; i < size; i++)
{
swap(str[i], str[index]);
printCombine2(str, index + 1, size);
swap(str[i], str[index]);
}
}
bool isSolution(int index, int size)
{
return index == size;
}
void processSolution(char *states, int statesSize)
{
if (states == NULL || statesSize <= 0)
return;
for (int i = 0; i < statesSize; i++)
cout << states[i] << " ";
cout << endl;
}
void generateCandidates(char *str, int size, char *states, char *candidates, int *ncandidates, int index)
{
if (str == NULL || size <= 0 || states == NULL || candidates == NULL || ncandidates == NULL)
return;
*ncandidates = 0;
for (int i = 0; i < size; i++)
{
int j;
for (j = 0; j < index; j++)
{
if (str[i] == states[j])
break;
}
if (j == index)
{
candidates[*ncandidates] = str[i];
*ncandidates = *ncandidates + 1;
}
}
}
void printCombine(char *str, int size, char *states, int statesSize, int index)
{
if (str == NULL || size <= 0 || states == NULL || statesSize <= 0 || index < 0 || index > statesSize)
return;
if (isSolution(index, statesSize) == true)
{
processSolution(states, statesSize);
}
else
{
int ncandidates;
char candidates[100];
generateCandidates(str, size, states, candidates, &ncandidates, index);
for (int i = 0; i < ncandidates; i++)
{
states[index] = candidates[i];
printCombine(str, size, states, statesSize, index + 1);
}
}
}
void main()
{
char states[100];
printCombine(str, size, states, size, 0);
}
面试题29: 数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字,例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
int array[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
const int size = sizeof array / sizeof *array;
int myPartition1(int *array, int size)
{
if (array == NULL || size <= 0)
return -1;
int pivot = array[size - 1];
int i = -1;
int j = 0;
while (j < size - 1)
{
if (array[j] < pivot)
{
i++;
swap(array[i], array[j]);
}
j++;
}
i++;
swap(array[i], array[j]);
return i;
}
int myPartition2(int *array, int left, int right)
{
if (array == NULL)
return -1;
if (left == right)
return left;
int leftIndex = left;
int rightIndex = right - 1;
int &pivot = array[right];
while (leftIndex <= rightIndex)
{
while (leftIndex < right && array[leftIndex] <= pivot)
leftIndex++;
while (rightIndex >= left && array[rightIndex] > pivot)
rightIndex--;
if (leftIndex > rightIndex)
break;
swap(array[leftIndex], array[rightIndex]);
}
swap(array[leftIndex], pivot);
return leftIndex;
}
int partitionIndex(int *array, int size, int k)
{
if (array == NULL || size <= 0 || k <= 0 || k > size)
return -1;
k = k - 1;
int pos = -1;
int left = 0;
int right = size - 1;
while (true)
{
pos = myPartition2(array, left, right);
if (pos < k)
left = pos + 1;
else if (pos > k)
right = pos - 1;
else
break;
}
return array[pos];
}
void main()
{
int result = partitionIndex(array, size, (size + 1) >> 1);
cout << "mid value = " << result << endl;
for (int i = 1; i <= size; i++)
{
int result = partitionIndex(array, size , i);
cout << "result = " << result << endl;
}
}
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
int array[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
const int size = sizeof array / sizeof *array;
int findMoreThanHalf(int *array, int size)
{
if (array == NULL || size <= 0)
return -1;
int candidate = array[0];
int count = 1;
for (int i = 1; i < size; i++)
{
if (count == 0)
{
candidate = array[i];
count = 1;
continue;
}
if (candidate == array[i])
count++;
else
count--;
}
return candidate;
}
void main()
{
int result = findMoreThanHalf(array, size);
cout << "result = " << result << endl;
}
面试题30:最小的K个数
题目:输入n个整数,找出其中最小的K个数,例如输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4
思路1:利用partition来求解,代码同上
思路2:利用最大堆来求解
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
void keepHeap(int *array, int position, int size)
{
if (array == NULL || size <= 0)
return;
int start = position;
int maxPos = start;
while (start < size / 2)
{
int leftChild = 2 * start + 1;
int rightChild = 2 * start + 2;
maxPos = start;
if (leftChild < size)
{
if (array[start] < array[leftChild])
maxPos = leftChild;
}
if (rightChild < size)
{
if (array[maxPos] < array[rightChild])
maxPos = rightChild;
}
if (maxPos != start)
{
swap(array[start], array[maxPos]);
start = maxPos;
}
else
break;
}
}
void buildMaxHeap(int *array, int size)
{
if (array == NULL || size <= 0)
return;
for (int i = (size - 1) / 2; i >= 0; i--)
keepHeap(array, i, size);
}
void getKMin(int *data, int size, int *array, int k)
{
if (data == NULL || size <= 0 || array == NULL || k <= 0)
return;
if (k >= size)
{
for (int i = 0; i < size; i++)
array[i] = data[i];
copy(array, array + size, ostream_iterator<int>(cout, " "));
return;
}
else
{
for (int i = 0; i < k; i++)
array[i] = data[i];
}
buildMaxHeap(array, k);
for (int i = k; i < size; i++)
{
if (data[i] < array[0])
{
array[0] = data[i];
keepHeap(array, 0, k);
}
}
copy(array, array + k, ostream_iterator<int>(cout, " "));
}
void main()
{
const int k = 5;
int array[k];
int data[] = {5, 4, 1, 9, 8, 7, 6, 2, 3};
const int size = sizeof data / sizeof *data;
getKMin(data, size, array, k);
}
UT:
1. k的取值问题,如果k为负数、0、正数(比size小,和size一样大,比size大)
2. 数组data的值选取
思路3:利用计数排序的思想来求解
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
const int maxNumber = 20;
void getKMin(int *data, int size, int *array, int k)
{
if (data == NULL || size <= 0 || array == NULL || k <= 0)
return;
if (k >= size)
{
for (int i = 0; i < size; i++)
array[i] = data[i];
copy(array, array + size, ostream_iterator<int>(cout, " "));
return;
}
int count[maxNumber];
for (int i = 0; i < maxNumber; i++)
count[i] = 0;
for (int i = 0; i < size; i++)
{
count[data[i]]++;
}
int index = 0;
for (int i = 0; i < maxNumber; i++)
{
for (int j = 0; j < count[i]; j++)
{
array[index] = i;
index++;
if (index == k)
goto here;
}
}
here:
copy(array, array + k, ostream_iterator<int>(cout, " "));
}
void main()
{
const int k = 5;
int array[k];
int data[] = {5, 4, 1, 9, 8, 7, 6, 2, 3};
const int size = sizeof data / sizeof *data;
getKMin(data, size, array, 5);
}
面试题31:连续子数组的最大和
题目:输入一个整形数组,数组里有正数也有负数,数组中一个或连续的多个整数组成一个子数组,求所有子数组和的最大值,要求时间复杂度为O(N)
#include <iostream>
using namespace std;
int array[] = {-2, 5, 3, -6, 4, -8, 6};
const int size = sizeof array / sizeof *array;
bool gStatus = false;
int getMaxSum(int *array, int size)
{
if (array == NULL || size <= 0)
{
gStatus = true;
return -1;
}
int maxSum = -65535;
int tempSum = 0;
for (int i = 0; i < size; i++)
{
tempSum += array[i];
if (tempSum > maxSum)
maxSum = tempSum;
if (tempSum < 0)
tempSum = 0;
}
return maxSum;
}
int getMaxSum2(int *array, int size)
{
if (array == NULL || size <= 0)
{
gStatus = true;
return -1;
}
int maxInclude = array[0];
int maxExclude = array[0];
for (int i = 1; i < size; i++)
{
maxExclude = max(maxInclude, maxExclude);
maxInclude = max(array[i] + maxInclude, array[i]);
}
return max(maxInclude, maxExclude);
}
void main()
{
int result = getMaxSum2(array, size);
cout << "result = " << result << endl;
}
面试题32:从1到n正数中1出现的次数
题目:输入一个正数n,求从1到n这n个整数的十进制表示中1出现的次数,例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1共出现了5次。
#include <iostream>
using namespace std;
int getOneNumber(int number)
{
int count = 0;
int currentNumber;
int preNumber;
int posNumber;
int position = 1;
while (number / position)
{
currentNumber = (number / position) % 10;
preNumber = number / (position * 10);
posNumber = number % position;
switch (currentNumber)
{
case 0:
count += preNumber * position;
break;
case 1:
count += preNumber * position + posNumber + 1;
break;
default:
count += (preNumber + 1) * position;
break;
}
position *= 10;
}
return count;
}
void main()
{
int number = getOneNumber(123);
cout << "number = " << number << endl;
}
话说书上的递归解我就想不出来。。。
#include <iostream>
using namespace std;
const char *input = "123";
int myExp(int base, int exp)
{
int result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
int getOneNumber(const char *input)
{
if (input == NULL || *input < '0' || *input > '9' || *input == '\0')
return 0;
int length = strlen(input);
int currentNumber = input[0] - '0';
if (length == 1)
{
if (currentNumber == 0)
return 0;
else
return 1;
}
int currentCount;
int otherCount;
if (currentNumber == 1)
{
currentCount = atoi(input + 1) + 1;
}
else
{
currentCount = myExp(10, length - 1);
}
otherCount = currentNumber * (length - 1) * myExp(10, length - 2);
return currentCount + otherCount + getOneNumber(input + 1);
}
void main()
{
int result = getOneNumber(input);
cout << "result = " << result << endl;
}
面试题33:把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接处的所有数字钟最小的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323
#include <iostream>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <string>
using namespace std;
int compare(const char *lhs, const char *rhs, char *lhsCatRhs, char *rhsCatLhs)
{
if (lhs == NULL || rhs == NULL)
return false;
int lenLhs = strlen(lhs);
int lenRhs = strlen(rhs);
strncpy(lhsCatRhs, lhs, lenLhs);
strncpy(lhsCatRhs + lenLhs, rhs, lenRhs);
lhsCatRhs[lenLhs + lenRhs] = 0;
strncpy(rhsCatLhs, rhs, lenRhs);
strncpy(rhsCatLhs + lenRhs, lhs, lenLhs);
rhsCatLhs[lenLhs + lenRhs] = 0;
return strcmp(lhsCatRhs, rhsCatLhs);
}
string myItoa(int number)
{
stringstream ss;
ss.str("");
ss << number;
string str = ss.str();
return str.c_str();
}
int partition(int *array, int left, int right, char *lhsCatRhs, char *rhsCatLhs)
{
if (array == NULL)
return -1;
int leftIndex = left;
int& pivot = array[right];
int rightIndex = right - 1;
while (leftIndex < right)
{
while (leftIndex < right && compare(myItoa(array[leftIndex]).c_str(), myItoa(pivot).c_str(), lhsCatRhs, rhsCatLhs) <= 0)
leftIndex++;
while (rightIndex >= 0 && compare(myItoa(array[rightIndex]).c_str(), myItoa(pivot).c_str(), lhsCatRhs, rhsCatLhs) > 0)
rightIndex--;
if (leftIndex > rightIndex)
break;
swap(array[leftIndex], array[rightIndex]);
}
swap(array[leftIndex], pivot);
return leftIndex;
}
void fastSort(int *array, int start, int end, char *lhsCatRhs, char *rhsCatLhs)
{
if (array == NULL || start >= end)
return;
int pos = partition(array, start, end, lhsCatRhs, rhsCatLhs);
fastSort(array, start, pos - 1, lhsCatRhs, rhsCatLhs);
fastSort(array, pos + 1, end, lhsCatRhs, rhsCatLhs);
}
void getMinNumber(int *array, int size, int maxDigits)
{
if (array == NULL || size <= 0)
return;
char *lhsCatRhs = new char[maxDigits + 1];
char *rhsCatLhs = new char[maxDigits + 1];
fastSort(array, 0, size - 1, lhsCatRhs, rhsCatLhs);
copy(array, array + size, ostream_iterator<int>(cout, " "));
cout << endl;
delete []lhsCatRhs;
delete []rhsCatLhs;
}
void main()
{
const int size = 3;
int array[size] = {3, 32, 321};
const int maxDigits = 10;
getMinNumber(array, size, maxDigits);
}
面试题34:丑数
题目:我们把只包含因子2、3和5的数称作丑数,求按从小到大的顺序的第1500个丑数。
#include <iostream>
using namespace std;
long long int findUglyNumber(int count)
{
long long int *pUglyNumbers = new long long int[count];
*pUglyNumbers = 1;
long long int *pUglyNumbersTwo = pUglyNumbers;
long long int *pUglyNumbersThree = pUglyNumbers;
long long int *pUglyNumbersFive = pUglyNumbers;
int i = 1;
while (i < count)
{
pUglyNumbers[i] = min(min(*pUglyNumbersTwo * 2, *pUglyNumbersThree * 3), *pUglyNumbersFive * 5);
while (*pUglyNumbersTwo * 2 <= pUglyNumbers[i])
pUglyNumbersTwo++;
while (*pUglyNumbersThree * 3 <= pUglyNumbers[i])
pUglyNumbersThree++;
while (*pUglyNumbersFive * 5 <= pUglyNumbers[i])
pUglyNumbersFive++;
++i;
}
long long int ugly = pUglyNumbers[count - 1];
delete[] pUglyNumbers;
return ugly;
}
void main()
{
long long int result = findUglyNumber(4);
cout << "result = " << result << endl;
}
面试题35:第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出b
#include <iostream>
using namespace std;
char findFirstChar(const char *str)
{
if (str == NULL)
return '\0';
char result = '\0';
const int length = strlen(str);
const int size = 256;
int hashBuff[size];
for (int i = 0; i < size; i++)
hashBuff[i] = 0;
for (int i = 0; i < length; i++)
{
hashBuff[str[i]]++;
}
for (int i = 0; i <size; i++)
{
if (hashBuff[str[i]] == 1)
{
result = str[i];
break;
}
}
return result;
}
void main()
{
const char *str = "abaccdeff";
char result = findFirstChar(str);
cout << "result = " << result << endl;
}
面试题36:数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则两个数字组成一个逆序对,输入一个数组,求出这个数组中的逆序对总数
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
const int size = 4;
int tempArray[size];
int findReversePair(int *array, int leftIndex, int rightIndex)
{
if (array == NULL)
return -1;
if (leftIndex == rightIndex)
return 0;
int midIndex = (leftIndex + rightIndex) >> 1;
int count = 0;
int leftCount = findReversePair(array, leftIndex, midIndex);
int rightCount = findReversePair(array, midIndex + 1, rightIndex);
for (int i = leftIndex; i <= midIndex; i++)
tempArray[i] = array[i];
for (int i = midIndex + 1; i <= rightIndex; i++)
tempArray[i] = array[i];
int i = leftIndex;
int j = midIndex + 1;
int k = leftIndex;
while (i <= midIndex && j <= rightIndex)
{
if (tempArray[i] > tempArray[j])
{
array[k] = tempArray[j];
count += midIndex - i + 1;
j++;
k++;
}
else
{
array[k] = tempArray[i];
i++;
k++;
}
}
if (i == midIndex + 1)
{
for (int m = j; m <= rightIndex; m++)
array[k++] = tempArray[m];
}
else if (j == rightIndex + 1)
{
for (int m = i; m <= midIndex; m++)
array[k++] = tempArray[m];
}
return count + leftCount + rightCount;
}
void main()
{
int array[] = {7, 5, 6, 4};
int result = findReversePair(array, 0, size - 1);
cout << "result = " << result << endl;
copy(array, array + size, ostream_iterator<int>(cout, " "));
}
面试题37:两个链表的第一个公共结点
题目:输入连个链表,找出它们的第一个公共结点。
1 2 3
6 7
4 5
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL) : data(i), next(pLeft) {}
int data;
Node *next;
};
void constructLink(Node *&head1, Node *&head2)
{
Node *node7 = new Node(7);
Node *node6 = new Node(6, node7);
Node *node5 = new Node(5, node6);
Node *node4 = new Node(4, node5);
Node *node3 = new Node(3, node6);
Node *node2 = new Node(2, node3);
Node *node1 = new Node(1,node2);
head1 = node1;
head2 = node4;
}
Node *findFirstCommonNode(Node *head1, Node *head2)
{
if (head1 == NULL || head2 == NULL)
return NULL;
int head1Len = 0;
int head2Len = 0;
Node *pHead1 = head1;
Node *pHead2 = head2;
while (pHead1 != NULL)
{
head1Len++;
pHead1 = pHead1->next;
}
while (pHead2 != NULL)
{
head2Len++;
pHead2 = pHead2->next;
}
pHead1 = head1;
pHead2 = head2;
if (head1Len > head2Len)
{
int dist = head1Len - head2Len;
while (dist)
{
pHead1 = pHead1->next;
dist--;
}
}
if (head1Len < head2Len)
{
int dist = head2Len - head1Len;
while (dist)
{
pHead2 = pHead2->next;
dist--;
}
}
while (pHead1 != NULL && pHead2 != NULL && pHead1 != pHead2)
{
pHead1 = pHead1->next;
pHead2 = pHead2->next;
}
return pHead1;
}
void main()
{
Node *head1;
Node *head2;
constructLink(head1, head2);
Node *commonNode = findFirstCommonNode(head1, head2);
cout << "common node: " << commonNode->data << endl;
}
面试题38:数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数,例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现4次,所有输出4
#include <iostream>
using namespace std;
int array[] = {3, 3, 3, 3, 3, 3, 3, 5};
const int size = sizeof array /sizeof *array;
int binarySearchLeftIndex(int *array, int size, int value)
{
if (array == NULL || size <= 0)
return -1;
int leftIndex = 0;
int rightIndex = size - 1;
while (leftIndex != rightIndex)
{
int midIndex = (leftIndex + rightIndex) >> 1;
if (array[midIndex] < value)
leftIndex = midIndex + 1;
else
rightIndex = midIndex;
}
if (array[leftIndex] == value)
return leftIndex;
else
return -1;
}
int binarySearchRightIndex(int *array, int size, int value)
{
if (array == NULL || size <= 0)
return -1;
int leftIndex = 0;
int rightIndex = size - 1;
while (leftIndex != rightIndex)
{
int midIndex = (leftIndex + rightIndex + 1) >> 1;
if (array[midIndex] > value)
rightIndex = midIndex - 1;
else
leftIndex = midIndex;
}
if (array[leftIndex] == value)
return leftIndex;
else
return -1;
}
void main()
{
int indexLeft = binarySearchLeftIndex(array, size, 3);
int indexRight = binarySearchRightIndex(array, size, 3);
int count;
if (indexLeft > -1 && indexRight > -1)
count = indexRight - indexLeft + 1;
else
count = 0;
cout << "count = " << count << endl;
}
面试题39:二叉树的深度
题目一:输入一棵二叉树的根节点,求该树的深度。从根节点到叶结点依次经历过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为数的深度。
题目二:输入一棵二叉树的根节点,判断该树是不是平衡二叉树,如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
1
2 3
4 5 6
7
#include <iostream>
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;
};
int getBinaryTreeDepth(Node *root)
{
if (root == NULL)
return 0;
int leftDepth = getBinaryTreeDepth(root->left);
int rightDepth = getBinaryTreeDepth(root->right);
return max(leftDepth, rightDepth) + 1;
}
Node *construct()
{
Node *node7 = new Node(7);
Node *node6 = new Node(6);
Node *node5 = new Node(5, node7);
Node *node4 = new Node(4);
Node *node3 = new Node(3, NULL, node6);
Node *node2 = new Node(2, node4, node5);
Node *node1 = new Node(1, node2, node3);
return node1;
}
void main()
{
Node *root = construct();
int depth = getBinaryTreeDepth(root);
cout << "depth = " << depth << endl;
}
#include <iostream>
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;
};
bool isEqualTree(Node *root, int &depth)
{
if (root == NULL) {
depth = 0;
return true;
}
int leftDepth;
int rightDepth;
bool leftFlag = isEqualTree(root->left, leftDepth);
bool rightFlag = isEqualTree(root->right, rightDepth);
bool flag;
depth = max(leftDepth, rightDepth) + 1;
if (leftDepth - rightDepth < -1 || leftDepth - rightDepth > 1)
flag = false;
else
flag = true;
return leftFlag && rightFlag && flag;
}
Node *construct()
{
Node *node10 = new Node(10);
Node *node9 = new Node(9, NULL, node10);
Node *node8 = new Node(8);
Node *node7 = new Node(7, node8);
Node *node6 = new Node(6, NULL, node9);
Node *node5 = new Node(5, node7);
Node *node4 = new Node(4);
Node *node3 = new Node(3, NULL, node6);
Node *node2 = new Node(2, node4, node5);
Node *node1 = new Node(1, node2, node3);
return node1;
}
void main()
{
Node *root = construct();
int depth;
bool result = isEqualTree(root, depth);
if (result)
cout << "balanced" << endl;
else
cout << "unbalanced" << endl;
}
面试题40:数组中只出现一次的数字
题目:一个整型数组里除了两个数字以外,其他的数字都出现了两次。请写出程序找出这两个只出现一次的数字,要求时间复杂度是O(N),空间复杂度是O(1)
#include <iostream>
#include <vector>
using namespace std;
int array[] = {2, 4, 3, 6, 3, 2, 5, 5};
const int size = sizeof array /sizeof *array;
int findIndex(int number)
{
int flag = 0x01;
while ((number & flag) == 0)
{
flag <<= 1;
}
return flag;
}
void findDistinctTowNumbers(int *array, int size, int &numberOne, int &numberTwo)
{
if (array == NULL || size <= 0)
return;
int exclusive = array[0];
for (int i = 1; i < size; i++)
{
exclusive ^= array[i];
}
cout << "exclusive = " << exclusive << endl;
int index = findIndex(exclusive);
cout << "index = " << index << endl;
vector<int> leftVec;
vector<int> rightVec;
for (int i = 0; i < size; i++)
{
if (array[i] & index)
leftVec.push_back(array[i]);
else
rightVec.push_back(array[i]);
}
cout << "left vector" << endl;
copy(leftVec.begin(), leftVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "right vector" << endl;
copy(rightVec.begin(), rightVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
numberOne = leftVec[0];
numberTwo = rightVec[0];
for (int i = 1; i < leftVec.size(); i++)
numberOne ^= leftVec[i];
for (int i = 1; i < rightVec.size(); i++)
numberTwo ^= rightVec[i];
}
void main()
{
int numberOne;
int numberTwo;
findDistinctTowNumbers(array, size, numberOne, numberTwo);
cout << "numberOne = " << numberOne << endl;
cout << "numberTwo = " << numberTwo << endl;
}
面试题41:和为s的两个数字VS和为s的连续正数序列
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得他妈的和正好是s,如果有多对数字的和等于s,输出任意一对
#include <iostream>
using namespace std;
int array[] = {1, 2, 4, 7, 11, 15};
const int size = sizeof array / sizeof *array;
bool findDestTwoNumbers(int *array, int size, int sum, int &number1, int &number2)
{
if (array == NULL || size <= 0)
return false;
cout << "size = " << size << endl;
int leftIndex = 0;
int rightIndex = size - 1;
while (leftIndex < rightIndex)
{
int tempSum = array[leftIndex] + array[rightIndex];
if (tempSum == sum)
break;
else if (tempSum < sum)
leftIndex++;
else
rightIndex--;
}
if (leftIndex == rightIndex)
return false;
else
{
number1 = array[leftIndex];
number2 = array[rightIndex];
return true;
}
}
void main()
{
int number1;
int number2;
int sum = 15;
bool flag = findDestTwoNumbers(array, size, sum, number1, number2);
if (flag == true)
{
cout << "number1: = " << number1 << endl;
cout << "number2 = " << number2 << endl;
}
else
{
cout << "can't find these two numbers" << endl;
}
}
题目二:输入一个正数s,打印出所有和为s的连续正数序列(至少包含两个数字),例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5,4~6,和7~8
#include <iostream>
using namespace std;
int distSum(int leftIndex, int rightIndex)
{
int sum = 0;
for (int i = leftIndex; i <= rightIndex; i++)
{
sum += i;
}
return sum;
}
void print(int leftIndex, int rightIndex)
{
for (int i = leftIndex; i <= rightIndex; i++)
cout << i << " ";
cout << endl;
}
void printNumbers(int number)
{
if (number <= 2)
return;
int leftIndex = 1;
int rightIndex = 2;
while (leftIndex < rightIndex && rightIndex <= (number + 1) / 2)
{
int sum = distSum(leftIndex, rightIndex);
if (sum < number)
rightIndex++;
else if (sum > number)
leftIndex++;
else
{
print(leftIndex, rightIndex);
leftIndex++;
}
}
}
void main()
{
printNumbers(15);
}
面试题42:翻转单词顺序VS左旋字符串
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词中字符的顺序不变,为简单起见,标点符号和普通字符一同处理,例如输入字符串“I am a student." 输出”student. a am I"
#include <iostream>
using namespace std;
void reverseString(char *str, int start, int end)
{
if (str == NULL || start > end)
return;
for (int i = start, j = end; i < j; i++, j--)
swap(str[i], str[j]);
}
void reverseArrays(char *str)
{
if (str == NULL)
return;
reverseString(str, 0, strlen(str) - 1);
int left = 0;
int right = 0;
while (str[right] != '\0')
{
while (str[right] != '\0' && str[right] != ' ')
right++;
reverseString(str, left, right - 1);
left = right + 1;
if (str[right] != '\0')
right++;
}
}
void main()
{
char str[] = "I am a student.";
reverseArrays(str);
cout << "str = " << str << endl;
}
题目二:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部,请定义一个函数实现字符串左旋转操作的功能,比如输入字符串“abcdefg”和数字2,该函数将返回左旋转2位得到的结果“cdefgab”
#include <iostream>
using namespace std;
void reverseString(char *str, int start, int end)
{
if (str == NULL || start > end)
return;
for (int i = start, j = end; i < j; i++, j--)
swap(str[i], str[j]);
}
void reverArray(char *str, int pos)
{
pos = pos - 1;
reverseString(str, 0, pos);
reverseString(str, pos + 1, strlen(str) - 1);
reverseString(str, 0, strlen(str) - 1);
}
void main()
{
char str[] = "abcdefg";
reverArray(str, 2);
cout << "str = " << str << endl;
}
面试题43:n个骰子的点数
题目:把n个骰仍在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率
书上的递归解法:
int positiveExp(int base, int exp)
{
int result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
void posibility(double *array, int sum, int original, int number, int value)
{
if (array == NULL)
return;
if (number == 0)
{
array[sum - original]++;
return;
}
for (int i = 1; i <= value; i++)
posibility(array, sum + i, original, number - 1, value);
}
void caculatePosibility(int number, int value)
{
const int totalvalues = number * value - number + 1;
double*array = new double[totalvalues];
for (int i = 0; i < totalvalues; i++)
array[i] = 0;
posibility(array, 0, number, number, value);
//copy(array, array + totalvalues, ostream_iterator<int>(cout, " "));
int baseNumber = positiveExp(value, number);
for (int i = 0; i < totalvalues; i++)
array[i] /= baseNumber;
copy(array, array + totalvalues, ostream_iterator<double>(cout, " "));
double totalSum = 0;
for (int i = 0; i < totalvalues; i++)
totalSum += array[i];
cout << "sum = " << totalSum << endl;
}
void main()
{
caculatePosibility(6, 6);
}
利用回溯法:
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
const int value = 6;
const int number = 6;
bool isSolution(int index, int number)
{
return index == number;
}
int positiveExp(int base, int exp)
{
int result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
void processSolution(double *counts, int number, int sum)
{
counts[sum - number]++;
/*
int baseNumber = positiveExp(value, number);ToUTF8
for (int i = 0; i < totalNumbers; i++)
counts /= baseNumber;
copy(counts, counts + totalNumbers, ostream_iterator<double>(cout, " "));
cout << endl;*/
}
void generateCandidates(double *candidates, int &ncandidate, int number)
{
if (candidates == NULL)
return;
for (int i = 1;i <= number; i++)
candidates[i - 1] = i;
ncandidate = 6;
}
void process(double *numbers, int totalNumbers, int index, int number, int maxValue, int sum)
{
if (numbers == NULL)
return;
double candidates[6];
int ncandidates;
if (isSolution(index, number) == true)
{
processSolution(numbers, number, sum);
}
else
{
generateCandidates(candidates, ncandidates, maxValue);
for (int i = 0; i < ncandidates; i++)
{
process(numbers, totalNumbers, index + 1, number, maxValue, sum + candidates[i]);
}
}
}
void main()
{
const int maxValue = 6;
const int number = 6;
const int totalNumbers = maxValue * number - number + 1;
double numbers[totalNumbers];
for (int i = 0; i < totalNumbers; i++)
numbers[i] = 0;
int sum = 0;
process(numbers, totalNumbers, 0, number, maxValue, sum);
copy(numbers, numbers + totalNumbers, ostream_iterator<double>(cout, " "));
}
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
void printPosibility(int number, int maxValue)
{
int totalNumbers = number * maxValue - number + 1;
int **numbers = new int*[2];
for (int i = 0; i < 2; i++)
numbers[i] = new int[totalNumbers];
int flag = 0;
for (int i = number; i <= number * maxValue; i++)
{
numbers[0][i - number] = 0;
numbers[1][i - number] = 0;
}
for (int i = 1; i <= maxValue; i++)
numbers[flag][i - 1] = 1;
for (int i = 2; i <= number; i++)
{
flag = 1 - flag;
for (int j = i; j <= number * maxValue; j++)
{
numbers[flag][j - i] = 0;
for (int k = j - 1; k >= i- 1 && k >= j - 6; k--)
{
numbers[flag][j - i] += numbers[1 - flag][k - i + 1];
}
}
}
copy(numbers[flag], numbers[flag] + totalNumbers, ostream_iterator<int>(cout, " "));
}
void main()
{
printPosibility(6, 6);
}
面试题44:扑克牌的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的,2~10为数字本身,A为1,J为11, Q为12, K为13,而大小王可以看成任意的数字。
#include <iostream>
using namespace std;
bool isContinusArray(int *array, int size)
{
if (array == NULL || size <= 0)
return false;
int count = 0;
int countZero = 0;
while (array[countZero] == 0)
countZero++;
for (int i = countZero; i < size; i++)
{
int dist = array[i] - array[i - 1];
if (dist < 0)
dist = -dist;
if (dist == 0)
return false;
count += dist - 1;
}
if (count <= countZero)
return true;
else
return false;
}
void main()
{
int array[] = {0, 1, 2, 3, 4, 6, 7};
const int size = sizeof array / sizeof *array;
bool result = isContinusArray(array, size);
if (result == true)
cout << "right" << endl;
else
cout << "wrong" << endl;
}
面试题45:圆圈中最后剩下的数字
面试题:0, 1, 。。。, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求这个圆圈里剩下的最后一个数字。
#include <iostream>
#include <list>
using namespace std;
int lastRemainNumber(int n, int m)
{
if (n < 1 || m < 1)
return -1;
list<int> ilist;
for (int i = 0; i <= n; i++)
ilist.push_back(i);
cout << "source:" << endl;
copy(ilist.begin(), ilist.end(), ostream_iterator<int>(cout, " "));
cout << endl;
list<int>::iterator iter = ilist.begin();
while (ilist.size() != 1)
{
for (int i = 1; i < m; i++)
{
++iter;
if (iter == ilist.end())
iter = ilist.begin();
}
list<int>::iterator next = ++iter;
if (next == ilist.end())
next = ilist.begin();
--iter;
ilist.erase(iter);
iter = next;
copy(ilist.begin(), ilist.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
return *(iter);
}
void main()
{
int result = lastRemainNumber(4, 3);
cout << "result = " << result << endl;
}
int lastRemainNumber2(int m, int n)
{
if (n < 1 || m < 1)
return -1;
int last = 0;
for (int i = 1; i <= n; i++)
last = (last + m) % i;
return last;
}
面试题46:求1+2+。。。+n
面试题:求1+2+。。。+n,要求不能使用乘法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
#include <iostream>
using namespace std;
template<int n>
struct Sum
{
enum value {N = Sum<n - 1>::N + n};
};
template<>
struct Sum<1>
{
enum value { N = 1 };
};
void main()
{
cout << Sum<100>::N << endl;
}
#include <iostream>
using namespace std;
struct Sum
{
Sum() { count++; sum += count; }
static int count;
static int sum;
};
int Sum::count = 0;
int Sum::sum = 0;
void main()
{
Sum *pSum = new Sum[100];
cout << Sum::sum << endl;
delete[] pSum;
}
面试题47:不用加减乘除做加法
面试题:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算
#include <iostream>
using namespace std;
int addWithoutPlus(int leftNumber, int rightNumber)
{
while (rightNumber)
{
int temp1 = leftNumber & rightNumber;
int temp2 = leftNumber ^ rightNumber;
leftNumber = temp2 ^ (temp1 << 1);
rightNumber = leftNumber & (temp1 << 1);
rightNumber = rightNumber << 1;
}
return leftNumber;
}
void main()
{
int i = 1;
int j = 2;
int result = addWithoutPlus(4, 8);
cout << "result = " << result << endl;
}
面试题48:不能被继承的类
题目:用C++设计一个不能被继承的类
template<class T>
class UnDerivedClass
{
public:
friend T;
private:
UnDerivedClass() {}
~UnDerivedClass()
};
class UnDerivedClass2 : virtual public UnDerivedClass<UnDerivedClass2>
{
public:
UnDerivedClass2() {}
~UnDerivedClass2()
};
class Try : public UnDerivedClass2
{
public:
Try() {}
~Try() {}
};
面试题49:把字符串转换成整数
#include <iostream>
using namespace std;
bool gIsError = false;
int str2int(const char *str)
{
if (str == NULL)
{
gIsError = true;
return false;
}
int sum = 0;
const char *pStr = str;
bool isNegtive = false;
if (*pStr == '-')
{
pStr++;
isNegtive = true;
}
while (*pStr != '\0')
{
if (*pStr >= '0' && *pStr <= '9')
{
sum = sum * 10 + *pStr - '0';
pStr++;
}
else
{
gIsError = true;
break;
}
}
if (isNegtive == true)
return -sum;
else
return sum;
}
void main()
{
int result = str2int("-100a00");
if (gIsError == true)
{
cout << "input error" << endl;
cout << "wrong result = " << result << endl;
return;
}
else
{
cout << "result = " << result << endl;
}
}
面试题50:树中两个结点的最低公共祖先
#include <iostream>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft),
right(pRight) {}
Node *left;
Node *right;
int data;
};
Node *constructNode(Node **pNode1, Node **pNode2)
{
Node *node12 = new Node(12);
Node *node11 = new Node(11);
Node *node10 = new Node(10);
Node *node9 = new Node(9, NULL, node12);
Node *node8 = new Node(8, node11, NULL);
Node *node7 = new Node(7);
Node *node6 = new Node(6);
Node *node5 = new Node(5, node8, node9);
Node *node4 = new Node(4, node10);
Node *node3 = new Node(3, node6, node7);
Node *node2 = new Node(2, node4, node5);
Node *node1 = new Node(1, node2, node3);
*pNode1 = node8;
*pNode2 = node12;
return node1;
}
bool isNodeIn(Node *root, Node *node)
{
if (root == NULL || node == NULL)
return false;
return (root == node) || isNodeIn(root->left, node) || isNodeIn(root->right, node);
}
Node *findLowestCommonFather(Node *root, Node *node1, Node *node2)
{
if (root == NULL || node1 == NULL || node2 == NULL)
return NULL;
bool leftFlagNode1 = isNodeIn(root->left, node1);
bool rightFlagNode1 = isNodeIn(root->right, node1);
bool leftFlagNode2 = isNodeIn(root->left, node2);
bool rightFlagNode2 = isNodeIn(root->right, node2);
if ((leftFlagNode1 == true && rightFlagNode2 == true) || (leftFlagNode2 == true && rightFlagNode1 == true))
return root;
else if (leftFlagNode1 == true || leftFlagNode2 == true)
return findLowestCommonFather(root->left, node1, node2);
else
return findLowestCommonFather(root->right, node1, node2);
}
bool findLowestCommonFather2(Node *root, Node *node1, Node *node2, Node *&father)
{
if (root == NULL || node1 == NULL || node2 == NULL)
return false;
if (root == node1 || root == node2)
return true;
bool leftFlag = findLowestCommonFather2(root->left, node1, node2, father);
bool rightFlag = findLowestCommonFather2(root->right, node1, node2, father);
if (leftFlag == true && rightFlag == true)
{
father = root;
return true;
}
else if (leftFlag == true)
return findLowestCommonFather2(root->left, node1, node2, father);
else
return findLowestCommonFather2(root->right, node1, node2, father);
}
void main()
{
Node *node1;
Node *node2;
Node *root = constructNode(&node1, &node2);
Node *father;
bool result = findLowestCommonFather2(root, node1, node2, father);
if (result != NULL)
cout << "father = " << father->data << endl;
else
cout << "no common father" << endl;
}