目录:
1、【剑指Offer学习】【面试题01:实现赋值运算符函数】
2、【剑指Offer学习】【面试题02:实现Singleton 模式——七种实现方式】
6、【剑指Offer学习】【面试题06:重建二叉树】
7、【剑指Offer学习】【面试题07:用两个栈实现队列】
8、【剑指Offer学习】【面试题08:旋转数组的最小数字】
10、【剑指Offer学习】【面试题10:二进制中1 的个数】
1、【剑指Offer学习】【面试题01:实现赋值运算符函数】
//================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题1:赋值运算符函数 // 题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。 #include<cstring> #include<cstdio> class CMyString { public: CMyString(char* pData = nullptr); CMyString(const CMyString& str); ~CMyString(void); CMyString& operator = (const CMyString& str); void Print(); private: char* m_pData; }; CMyString::CMyString(char *pData) { if(pData == nullptr) { m_pData = new char[1]; m_pData[0] = '\0'; } else { int length = strlen(pData); m_pData = new char[length + 1]; strcpy(m_pData, pData); } } CMyString::CMyString(const CMyString &str) { int length = strlen(str.m_pData); m_pData = new char[length + 1]; strcpy(m_pData, str.m_pData); } CMyString::~CMyString() { delete[] m_pData; } CMyString& CMyString::operator = (const CMyString& str) { if(this == &str) return *this; delete []m_pData; m_pData = nullptr; m_pData = new char[strlen(str.m_pData) + 1]; strcpy(m_pData, str.m_pData); return *this; } // ====================测试代码==================== void CMyString::Print() { printf("%s", m_pData); } void Test1() { printf("Test1 begins:\n"); char* text = "Hello world"; CMyString str1(text); CMyString str2; str2 = str1; printf("The expected result is: %s.\n", text); printf("The actual result is: "); str2.Print(); printf(".\n"); } // 赋值给自己 void Test2() { printf("Test2 begins:\n"); char* text = "Hello world"; CMyString str1(text); str1 = str1; printf("The expected result is: %s.\n", text); printf("The actual result is: "); str1.Print(); printf(".\n"); } // 连续赋值 void Test3() { printf("Test3 begins:\n"); char* text = "Hello world"; CMyString str1(text); CMyString str2, str3; str3 = str2 = str1; printf("The expected result is: %s.\n", text); printf("The actual result is: "); str2.Print(); printf(".\n"); printf("The expected result is: %s.\n", text); printf("The actual result is: "); str3.Print(); printf(".\n"); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); return 0; }
2、【剑指Offer学习】【面试题02:实现Singleton 模式——七种实现方式】
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题2:实现Singleton模式 // 题目:设计一个类,我们只能生成该类的一个实例。 using System; namespace _02_Singleton { public sealed class Singleton1 { private Singleton1() { } private static Singleton1 instance = null; public static Singleton1 Instance { get { if (instance == null) instance = new Singleton1(); return instance; } } } public sealed class Singleton2 { private Singleton2() { } private static readonly object syncObj = new object(); private static Singleton2 instance = null; public static Singleton2 Instance { get { lock (syncObj) { if (instance == null) instance = new Singleton2(); } return instance; } } } public sealed class Singleton3 { private Singleton3() { } private static object syncObj = new object(); private static Singleton3 instance = null; public static Singleton3 Instance { get { if (instance == null) { lock (syncObj) { if (instance == null) instance = new Singleton3(); } } return instance; } } } public sealed class Singleton4 { private Singleton4() { Console.WriteLine("An instance of Singleton4 is created."); } public static void Print() { Console.WriteLine("Singleton4 Print"); } private static Singleton4 instance = new Singleton4(); public static Singleton4 Instance { get { return instance; } } } public sealed class Singleton5 { Singleton5() { Console.WriteLine("An instance of Singleton5 is created."); } public static void Print() { Console.WriteLine("Singleton5 Print"); } public static Singleton5 Instance { get { return Nested.instance; } } class Nested { static Nested() { } internal static readonly Singleton5 instance = new Singleton5(); } } class Program { static void Main(string[] args) { // 也会打印An instance of Singleton4 is created. Singleton4.Print(); // 不会打印An instance of Singleton5 is created. Singleton5.Print(); } } }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题3(一):找出数组中重复的数字 // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3}, // 那么对应的输出是重复的数字2或者3。 #include <cstdio> // 参数: // numbers: 一个整数数组 // length: 数组的长度 // duplication: (输出) 数组中的一个重复的数字 // 返回值: // true - 输入有效,并且数组中存在重复的数字 // false - 输入无效,或者数组中没有重复的数字 bool duplicate(int numbers[], int length, int* duplication) { if(numbers == nullptr || length <= 0) return false; for(int i = 0; i < length; ++i) { if(numbers[i] < 0 || numbers[i] > length - 1) return false; } for(int i = 0; i < length; ++i) { while(numbers[i] != i) { if(numbers[i] == numbers[numbers[i]]) { *duplication = numbers[i]; return true; } // 交换numbers[i]和numbers[numbers[i]] int temp = numbers[i]; numbers[i] = numbers[temp]; numbers[temp] = temp; } } return false; } // ====================测试代码==================== bool contains(int array[], int length, int number) { for(int i = 0; i < length; ++i) { if(array[i] == number) return true; } return false; } void test(char* testName, int numbers[], int lengthNumbers, int expected[], int expectedExpected, bool validArgument) { printf("%s begins: ", testName); int duplication; bool validInput = duplicate(numbers, lengthNumbers, &duplication); if(validArgument == validInput) { if(validArgument) { if(contains(expected, expectedExpected, duplication)) printf("Passed.\n"); else printf("FAILED.\n"); } else printf("Passed.\n"); } else printf("FAILED.\n"); } // 重复的数字是数组中最小的数字 void test1() { int numbers[] = { 2, 1, 3, 1, 4 }; int duplications[] = { 1 }; test("Test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 重复的数字是数组中最大的数字 void test2() { int numbers[] = { 2, 4, 3, 1, 4 }; int duplications[] = { 4 }; test("Test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 数组中存在多个重复的数字 void test3() { int numbers[] = { 2, 4, 2, 1, 4 }; int duplications[] = { 2, 4 }; test("Test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true); } // 没有重复的数字 void test4() { int numbers[] = { 2, 1, 3, 0, 4 }; int duplications[] = { -1 }; // not in use in the test function test("Test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false); } // 没有重复的数字 void test5() { int numbers[] = { 2, 1, 3, 5, 4 }; int duplications[] = { -1 }; // not in use in the test function test("Test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false); } // 无效的输入 void test6() { int* numbers = nullptr; int duplications[] = { -1 }; // not in use in the test function test("Test6", numbers, 0, duplications, sizeof(duplications) / sizeof(int), false); } void main() { test1(); test2(); test3(); test4(); test5(); test6(); while(1); }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题3(二):不修改数组找出重复的数字 // 题目:在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至 // 少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的 // 数组。例如,如果输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},那么对应的 // 输出是重复的数字2或者3。 #include <iostream> int countRange(const int* numbers, int length, int start, int end); // 参数: // numbers: 一个整数数组 // length: 数组的长度 // 返回值: // 正数 - 输入有效,并且数组中存在重复的数字,返回值为重复的数字 // 负数 - 输入无效,或者数组中没有重复的数字 int getDuplication(const int* numbers, int length) { if(numbers == nullptr || length <= 0) return -1; int start = 1; int end = length - 1; while(end >= start) { int middle = ((end - start) >> 1) + start; int count = countRange(numbers, length, start, middle); if(end == start) { if(count > 1) return start; else break; } if(count > (middle - start + 1)) end = middle; else start = middle + 1; } return -1; } int countRange(const int* numbers, int length, int start, int end) { if(numbers == nullptr) return 0; int count = 0; for(int i = 0; i < length; i++) if(numbers[i] >= start && numbers[i] <= end) ++count; return count; } // ====================测试代码==================== void test(const char* testName, int* numbers, int length, int* duplications, int dupLength) { int result = getDuplication(numbers, length); for(int i = 0; i < dupLength; ++i) { if(result == duplications[i]) { std::cout << testName << " passed." << std::endl; return; } } std::cout << testName << " FAILED." << std::endl; } // 多个重复的数字 void test1() { int numbers[] = { 2, 3, 5, 4, 3, 2, 6, 7 }; int duplications[] = { 2, 3 }; test("test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 一个重复的数字 void test2() { int numbers[] = { 3, 2, 1, 4, 4, 5, 6, 7 }; int duplications[] = { 4 }; test("test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 重复的数字是数组中最小的数字 void test3() { int numbers[] = { 1, 2, 3, 4, 5, 6, 7, 1, 8 }; int duplications[] = { 1 }; test("test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 重复的数字是数组中最大的数字 void test4() { int numbers[] = { 1, 7, 3, 4, 5, 6, 8, 2, 8 }; int duplications[] = { 8 }; test("test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 数组中只有两个数字 void test5() { int numbers[] = { 1, 1 }; int duplications[] = { 1 }; test("test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 重复的数字位于数组当中 void test6() { int numbers[] = { 3, 2, 1, 3, 4, 5, 6, 7 }; int duplications[] = { 3 }; test("test6", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 多个重复的数字 void test7() { int numbers[] = { 1, 2, 2, 6, 4, 5, 6 }; int duplications[] = { 2, 6 }; test("test7", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 一个数字重复三次 void test8() { int numbers[] = { 1, 2, 2, 6, 4, 5, 2 }; int duplications[] = { 2 }; test("test8", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 没有重复的数字 void test9() { int numbers[] = { 1, 2, 6, 4, 5, 3 }; int duplications[] = { -1 }; test("test9", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int)); } // 无效的输入 void test10() { int* numbers = nullptr; int duplications[] = { -1 }; test("test10", numbers, 0, duplications, sizeof(duplications) / sizeof(int)); } void main() { test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); test9(); test10(); }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题4:二维数组中的查找 // 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按 // 照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个 // 整数,判断数组中是否含有该整数。 #include <cstdio> bool Find(int* matrix, int rows, int columns, int number) { bool found = false; if(matrix != nullptr && rows > 0 && columns > 0) { int row = 0; int column = columns - 1; while(row < rows && column >=0) { if(matrix[row * columns + column] == number) { found = true; break; } else if(matrix[row * columns + column] > number) -- column; else ++ row; } } return found; } // ====================测试代码==================== void Test(char* testName, int* matrix, int rows, int columns, int number, bool expected) { if(testName != nullptr) printf("%s begins: ", testName); bool result = Find(matrix, rows, columns, number); if(result == expected) printf("Passed.\n"); else printf("Failed.\n"); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数在数组中 void Test1() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test1", (int*)matrix, 4, 4, 7, true); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数不在数组中 void Test2() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test2", (int*)matrix, 4, 4, 5, false); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数是数组中最小的数字 void Test3() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test3", (int*)matrix, 4, 4, 1, true); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数是数组中最大的数字 void Test4() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test4", (int*)matrix, 4, 4, 15, true); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数比数组中最小的数字还小 void Test5() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test5", (int*)matrix, 4, 4, 0, false); } // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的数比数组中最大的数字还大 void Test6() { int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Test("Test6", (int*)matrix, 4, 4, 16, false); } // 鲁棒性测试,输入空指针 void Test7() { Test("Test7", nullptr, 0, 0, 16, false); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); return 0; }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题5:替换空格 // 题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”, // 则输出“We%20are%20happy.”。 #include <cstdio> #include <cstring> /*length 为字符数组str的总容量,大于或等于字符串str的实际长度*/ void ReplaceBlank(char str[], int length) { if(str == nullptr && length <= 0) return; /*originalLength 为字符串str的实际长度*/ int originalLength = 0; int numberOfBlank = 0; int i = 0; while(str[i] != '\0') { ++ originalLength; if(str[i] == ' ') ++ numberOfBlank; ++ i; } /*newLength 为把空格替换成'%20'之后的长度*/ int newLength = originalLength + numberOfBlank * 2; if(newLength > length) return; int indexOfOriginal = originalLength; int indexOfNew = newLength; while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal) { if(str[indexOfOriginal] == ' ') { str[indexOfNew --] = '0'; str[indexOfNew --] = '2'; str[indexOfNew --] = '%'; } else { str[indexOfNew --] = str[indexOfOriginal]; } -- indexOfOriginal; } } // ====================测试代码==================== void Test(char* testName, char str[], int length, char expected[]) { if(testName != nullptr) printf("%s begins: ", testName); ReplaceBlank(str, length); if(expected == nullptr && str == nullptr) printf("passed.\n"); else if(expected == nullptr && str != nullptr) printf("failed.\n"); else if(strcmp(str, expected) == 0) printf("passed.\n"); else printf("failed.\n"); } // 空格在句子中间 void Test1() { const int length = 100; char str[length] = "hello world"; Test("Test1", str, length, "hello%20world"); } // 空格在句子开头 void Test2() { const int length = 100; char str[length] = " helloworld"; Test("Test2", str, length, "%20helloworld"); } // 空格在句子末尾 void Test3() { const int length = 100; char str[length] = "helloworld "; Test("Test3", str, length, "helloworld%20"); } // 连续有两个空格 void Test4() { const int length = 100; char str[length] = "hello world"; Test("Test4", str, length, "hello%20%20world"); } // 传入nullptr void Test5() { Test("Test5", nullptr, 0, nullptr); } // 传入内容为空的字符串 void Test6() { const int length = 100; char str[length] = ""; Test("Test6", str, length, ""); } //传入内容为一个空格的字符串 void Test7() { const int length = 100; char str[length] = " "; Test("Test7", str, length, "%20"); } // 传入的字符串没有空格 void Test8() { const int length = 100; char str[length] = "helloworld"; Test("Test8", str, length, "helloworld"); } // 传入的字符串全是空格 void Test9() { const int length = 100; char str[length] = " "; Test("Test9", str, length, "%20%20%20"); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); Test8(); Test9(); return 0; }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题6:从尾到头打印链表 // 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。 #include "..\Utilities\List.h" #include <stack> void PrintListReversingly_Iteratively(ListNode* pHead) { std::stack<ListNode*> nodes; ListNode* pNode = pHead; while(pNode != nullptr) { nodes.push(pNode); pNode = pNode->m_pNext; } while(!nodes.empty()) { pNode = nodes.top(); printf("%d\t", pNode->m_nValue); nodes.pop(); } } void PrintListReversingly_Recursively(ListNode* pHead) { if(pHead != nullptr) { if (pHead->m_pNext != nullptr) { PrintListReversingly_Recursively(pHead->m_pNext); } printf("%d\t", pHead->m_nValue); } } // ====================测试代码==================== void Test(ListNode* pHead) { PrintList(pHead); PrintListReversingly_Iteratively(pHead); printf("\n"); PrintListReversingly_Recursively(pHead); } // 1->2->3->4->5 void Test1() { printf("\nTest1 begins.\n"); ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); Test(pNode1); DestroyList(pNode1); } // 只有一个结点的链表: 1 void Test2() { printf("\nTest2 begins.\n"); ListNode* pNode1 = CreateListNode(1); Test(pNode1); DestroyList(pNode1); } // 空链表 void Test3() { printf("\nTest3 begins.\n"); Test(nullptr); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); return 0; }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1, // 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建出 // 图2.6所示的二叉树并输出它的头结点。 #include "..\Utilities\BinaryTree.h" #include <exception> #include <cstdio> BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder); BinaryTreeNode* Construct(int* preorder, int* inorder, int length) { if(preorder == nullptr || inorder == nullptr || length <= 0) return nullptr; return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1); } BinaryTreeNode* ConstructCore ( int* startPreorder, int* endPreorder, int* startInorder, int* endInorder ) { // 前序遍历序列的第一个数字是根结点的值 int rootValue = startPreorder[0]; BinaryTreeNode* root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeft = root->m_pRight = nullptr; if(startPreorder == endPreorder) { if(startInorder == endInorder && *startPreorder == *startInorder) return root; else throw std::exception("Invalid input."); } // 在中序遍历中找到根结点的值 int* rootInorder = startInorder; while(rootInorder <= endInorder && *rootInorder != rootValue) ++ rootInorder; if(rootInorder == endInorder && *rootInorder != rootValue) throw std::exception("Invalid input."); int leftLength = rootInorder - startInorder; int* leftPreorderEnd = startPreorder + leftLength; if(leftLength > 0) { // 构建左子树 root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1); } if(leftLength < endPreorder - startPreorder) { // 构建右子树 root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder); } return root; } // ====================测试代码==================== void Test(char* testName, int* preorder, int* inorder, int length) { if(testName != nullptr) printf("%s begins:\n", testName); printf("The preorder sequence is: "); for(int i = 0; i < length; ++ i) printf("%d ", preorder[i]); printf("\n"); printf("The inorder sequence is: "); for(int i = 0; i < length; ++ i) printf("%d ", inorder[i]); printf("\n"); try { BinaryTreeNode* root = Construct(preorder, inorder, length); PrintTree(root); DestroyTree(root); } catch(std::exception& exception) { printf("Invalid Input.\n"); } } // 普通二叉树 // 1 // / \ // 2 3 // / / \ // 4 5 6 // \ / // 7 8 void Test1() { const int length = 8; int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8}; int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6}; Test("Test1", preorder, inorder, length); } // 所有结点都没有右子结点 // 1 // / // 2 // / // 3 // / // 4 // / // 5 void Test2() { const int length = 5; int preorder[length] = {1, 2, 3, 4, 5}; int inorder[length] = {5, 4, 3, 2, 1}; Test("Test2", preorder, inorder, length); } // 所有结点都没有左子结点 // 1 // \ // 2 // \ // 3 // \ // 4 // \ // 5 void Test3() { const int length = 5; int preorder[length] = {1, 2, 3, 4, 5}; int inorder[length] = {1, 2, 3, 4, 5}; Test("Test3", preorder, inorder, length); } // 树中只有一个结点 void Test4() { const int length = 1; int preorder[length] = {1}; int inorder[length] = {1}; Test("Test4", preorder, inorder, length); } // 完全二叉树 // 1 // / \ // 2 3 // / \ / \ // 4 5 6 7 void Test5() { const int length = 7; int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; int inorder[length] = {4, 2, 5, 1, 6, 3, 7}; Test("Test5", preorder, inorder, length); } // 输入空指针 void Test6() { Test("Test6", nullptr, nullptr, 0); } // 输入的两个序列不匹配 void Test7() { const int length = 7; int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; int inorder[length] = {4, 2, 8, 1, 6, 3, 7}; Test("Test7: for unmatched input", preorder, inorder, length); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); return 0; }
8、【剑指Offer学习】【面试题08:旋转数组的最小数字】
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题8:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。 #include <stdio.h> struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; BinaryTreeNode* m_pParent; }; BinaryTreeNode* GetNext(BinaryTreeNode* pNode) { if(pNode == nullptr) return nullptr; BinaryTreeNode* pNext = nullptr; if(pNode->m_pRight != nullptr) { BinaryTreeNode* pRight = pNode->m_pRight; while(pRight->m_pLeft != nullptr) pRight = pRight->m_pLeft; pNext = pRight; } else if(pNode->m_pParent != nullptr) { BinaryTreeNode* pCurrent = pNode; BinaryTreeNode* pParent = pNode->m_pParent; while(pParent != nullptr && pCurrent == pParent->m_pRight) { pCurrent = pParent; pParent = pParent->m_pParent; } pNext = pParent; } return pNext; } // ==================== 辅助代码用来构建二叉树 ==================== BinaryTreeNode* CreateBinaryTreeNode(int value) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = nullptr; pNode->m_pRight = nullptr; pNode->m_pParent = nullptr; return pNode; } void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) { if(pParent != nullptr) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; if(pLeft != nullptr) pLeft->m_pParent = pParent; if(pRight != nullptr) pRight->m_pParent = pParent; } } void PrintTreeNode(BinaryTreeNode* pNode) { if(pNode != nullptr) { printf("value of this node is: %d\n", pNode->m_nValue); if(pNode->m_pLeft != nullptr) printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue); else printf("left child is null.\n"); if(pNode->m_pRight != nullptr) printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue); else printf("right child is null.\n"); } else { printf("this node is null.\n"); } printf("\n"); } void PrintTree(BinaryTreeNode* pRoot) { PrintTreeNode(pRoot); if(pRoot != nullptr) { if(pRoot->m_pLeft != nullptr) PrintTree(pRoot->m_pLeft); if(pRoot->m_pRight != nullptr) PrintTree(pRoot->m_pRight); } } void DestroyTree(BinaryTreeNode* pRoot) { if(pRoot != nullptr) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = nullptr; DestroyTree(pLeft); DestroyTree(pRight); } } // ====================测试代码==================== void Test(char* testName, BinaryTreeNode* pNode, BinaryTreeNode* expected) { if(testName != nullptr) printf("%s begins: ", testName); BinaryTreeNode* pNext = GetNext(pNode); if(pNext == expected) printf("Passed.\n"); else printf("FAILED.\n"); } // 8 // 6 10 // 5 7 9 11 void Test1_7() { BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8); BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6); BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7); BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9); BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11); ConnectTreeNodes(pNode8, pNode6, pNode10); ConnectTreeNodes(pNode6, pNode5, pNode7); ConnectTreeNodes(pNode10, pNode9, pNode11); Test("Test1", pNode8, pNode9); Test("Test2", pNode6, pNode7); Test("Test3", pNode10, pNode11); Test("Test4", pNode5, pNode6); Test("Test5", pNode7, pNode8); Test("Test6", pNode9, pNode10); Test("Test7", pNode11, nullptr); DestroyTree(pNode8); } // 5 // 4 // 3 // 2 void Test8_11() { BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); ConnectTreeNodes(pNode5, pNode4, nullptr); ConnectTreeNodes(pNode4, pNode3, nullptr); ConnectTreeNodes(pNode3, pNode2, nullptr); Test("Test8", pNode5, nullptr); Test("Test9", pNode4, pNode5); Test("Test10", pNode3, pNode4); Test("Test11", pNode2, pNode3); DestroyTree(pNode5); } // 2 // 3 // 4 // 5 void Test12_15() { BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNode2, nullptr, pNode3); ConnectTreeNodes(pNode3, nullptr, pNode4); ConnectTreeNodes(pNode4, nullptr, pNode5); Test("Test12", pNode5, nullptr); Test("Test13", pNode4, pNode5); Test("Test14", pNode3, pNode4); Test("Test15", pNode2, pNode3); DestroyTree(pNode2); } void Test16() { BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); Test("Test16", pNode5, nullptr); DestroyTree(pNode5); } int main(int argc, char* argv[]) { Test1_7(); Test8_11(); Test12_15(); Test16(); }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题9:用两个栈实现队列 // 题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail // 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。 #include "Queue.h" // ====================测试代码==================== void Test(char actual, char expected) { if(actual == expected) printf("Test passed.\n"); else printf("Test failed.\n"); } int main(int argc, char* argv[]) { CQueue<char> queue; queue.appendTail('a'); queue.appendTail('b'); queue.appendTail('c'); char head = queue.deleteHead(); Test(head, 'a'); head = queue.deleteHead(); Test(head, 'b'); queue.appendTail('d'); head = queue.deleteHead(); Test(head, 'c'); queue.appendTail('e'); head = queue.deleteHead(); Test(head, 'd'); head = queue.deleteHead(); Test(head, 'e'); return 0; }
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题9:用两个栈实现队列 // 题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail // 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。 #pragma once #include <stack> #include <exception> using namespace std; template <typename T> class CQueue { public: CQueue(void); ~CQueue(void); // 在队列末尾添加一个结点 void appendTail(const T& node); // 删除队列的头结点 T deleteHead(); private: stack<T> stack1; stack<T> stack2; }; template <typename T> CQueue<T>::CQueue(void) { } template <typename T> CQueue<T>::~CQueue(void) { } template<typename T> void CQueue<T>::appendTail(const T& element) { stack1.push(element); } template<typename T> T CQueue<T>::deleteHead() { if(stack2.size()<= 0) { while(stack1.size()>0) { T& data = stack1.top(); stack1.pop(); stack2.push(data); } } if(stack2.size() == 0) throw new exception("queue is empty"); T head = stack2.top(); stack2.pop(); return head; }
10、【剑指Offer学习】【面试题10:二进制中1 的个数】
/******************************************************************* Copyright(c) 2016, Harry He All rights reserved. Distributed under the BSD license. (See accompanying file LICENSE.txt at https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt) *******************************************************************/ //================================================================== // 《剑指Offer——名企面试官精讲典型编程题》代码 // 作者:何海涛 //================================================================== // 面试题10:斐波那契数列 // 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。 #include <cstdio> // ====================方法1:递归==================== long long Fibonacci_Solution1(unsigned int n) { if(n <= 0) return 0; if(n == 1) return 1; return Fibonacci_Solution1(n - 1) + Fibonacci_Solution1(n - 2); } // ====================方法2:循环==================== long long Fibonacci_Solution2(unsigned n) { int result[2] = {0, 1}; if(n < 2) return result[n]; long long fibNMinusOne = 1; long long fibNMinusTwo = 0; long long fibN = 0; for(unsigned int i = 2; i <= n; ++ i) { fibN = fibNMinusOne + fibNMinusTwo; fibNMinusTwo = fibNMinusOne; fibNMinusOne = fibN; } return fibN; } // ====================方法3:基于矩阵乘法==================== #include <cassert> struct Matrix2By2 { Matrix2By2 ( long long m00 = 0, long long m01 = 0, long long m10 = 0, long long m11 = 0 ) :m_00(m00), m_01(m01), m_10(m10), m_11(m11) { } long long m_00; long long m_01; long long m_10; long long m_11; }; Matrix2By2 MatrixMultiply ( const Matrix2By2& matrix1, const Matrix2By2& matrix2 ) { return Matrix2By2( matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10, matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11, matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10, matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11); } Matrix2By2 MatrixPower(unsigned int n) { assert(n > 0); Matrix2By2 matrix; if(n == 1) { matrix = Matrix2By2(1, 1, 1, 0); } else if(n % 2 == 0) { matrix = MatrixPower(n / 2); matrix = MatrixMultiply(matrix, matrix); } else if(n % 2 == 1) { matrix = MatrixPower((n - 1) / 2); matrix = MatrixMultiply(matrix, matrix); matrix = MatrixMultiply(matrix, Matrix2By2(1, 1, 1, 0)); } return matrix; } long long Fibonacci_Solution3(unsigned int n) { int result[2] = {0, 1}; if(n < 2) return result[n]; Matrix2By2 PowerNMinus2 = MatrixPower(n - 1); return PowerNMinus2.m_00; } // ====================测试代码==================== void Test(int n, int expected) { if(Fibonacci_Solution1(n) == expected) printf("Test for %d in solution1 passed.\n", n); else printf("Test for %d in solution1 failed.\n", n); if(Fibonacci_Solution2(n) == expected) printf("Test for %d in solution2 passed.\n", n); else printf("Test for %d in solution2 failed.\n", n); if(Fibonacci_Solution3(n) == expected) printf("Test for %d in solution3 passed.\n", n); else printf("Test for %d in solution3 failed.\n", n); } int main(int argc, char* argv[]) { Test(0, 0); Test(1, 1); Test(2, 1); Test(3, 2); Test(4, 3); Test(5, 5); Test(6, 8); Test(7, 13); Test(8, 21); Test(9, 34); Test(10, 55); Test(40, 102334155); return 0; }
来源:https://www.cnblogs.com/agui125/p/12020184.html