学习笔记之15道简单算法题
All contents are moved to haoran119/interview (github.com)
15道简单算法题
http://www.cnblogs.com/hlxs/archive/2014/06/06/3772333.html
(●—●) | 剑指Offer_编程题_牛客网
http://www.nowcoder.com/ta/coding-interviews?page=1
source code
interview/学习笔记之15道简单算法题 at main · haoran119/interview (github.com)
1:合并排序,将两个已经排序的数组合并成一个数组,其中一个数组能容下两个数组的所有元素;
1 #include <iostream> 2 using namespace std; 3 4 class Solution 5 { 6 public: 7 void MergeArray(int a[],int alen,int b[],int blen) 8 { 9 int len = alen + blen - 1; 10 alen --; 11 blen --; 12 13 // 用归并排序的思想把两个数组合并 14 while (alen >= 0 && blen >= 0) 15 { 16 if (a[alen] > b[blen]) 17 a[len --] = a[alen --]; 18 else 19 a[len --] = b[blen --]; 20 } 21 22 while (blen >= 0) 23 a[len --] = b[blen --]; 24 } 25 }; 26 27 int main () 28 { 29 Solution testSolution; 30 int arrA[] = {1, 2, 4, 6, 8, 0, 0, 0, 0, 0}; 31 int arrB[] = {1, 3, 5, 7, 9}; 32 33 testSolution.MergeArray(arrA, 5, arrB, 5); 34 35 for (int i = 0; i < 10; i ++) 36 cout << arrA[i] << endl; 37 38 getchar(); 39 40 return 0; 41 }
2:合并两个单链表;
- C++11最好用nullptr初始化指针得到空指针,同时尽量避免使用NULL。
- https://msdn.microsoft.com/zh-cn/library/4ex65770.aspx
- 复习struct,链表也不熟悉了,用当前节点还是next节点的时候出了几次错。
- struct_百度百科
- http://baike.baidu.com/link?url=PxVQxXElF_rtYMqYhfNBzsjvTl9cG2PSKTqFZGV3IBAEHosImlkuaSMqCIxnShEqtDD4xA8gISTtP7rS7TENj_
- struct (C++)
- https://msdn.microsoft.com/zh-cn/library/64973255.aspx
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 ListNode* MergeList(ListNode* aListNode, ListNode* bListNode) 15 { 16 // NULL case 17 if (aListNode == NULL) 18 return bListNode; 19 if (bListNode == NULL) 20 return aListNode; 21 22 ListNode* resHead = NULL; 23 24 if (aListNode->val < bListNode->val) { 25 resHead = aListNode; 26 aListNode = aListNode->next; 27 } else { 28 resHead = bListNode; 29 bListNode = bListNode->next; 30 } 31 32 // Reserve the head point 33 ListNode* tmpHead = resHead; 34 35 // PrintListNode(tmpHead); 36 37 // Merge two LinkList 38 // Remember to check if the current node is NULL 39 // assign ListNode to next resHead->next 40 // move resHead to the next ptr 41 while (aListNode != NULL && bListNode != NULL) 42 { 43 if (aListNode->val < bListNode->val) { 44 resHead->next = aListNode; 45 aListNode = aListNode->next; 46 } else { 47 resHead->next= bListNode; 48 bListNode = bListNode->next; 49 } 50 resHead = resHead->next; 51 } 52 53 // PrintListNode(tmpHead); 54 55 if (aListNode != NULL) 56 resHead->next= aListNode; 57 58 if (bListNode != NULL) 59 resHead->next= bListNode; 60 61 // PrintListNode(tmpHead); 62 63 return tmpHead; 64 } 65 66 void PrintListNode(ListNode* inListNode) 67 { 68 ListNode* tmpLN = inListNode; 69 70 while (tmpLN != NULL) 71 { 72 cout << tmpLN->val << endl; 73 tmpLN = tmpLN->next; 74 } 75 cout << endl; 76 } 77 }; 78 79 int main () 80 { 81 Solution testSolution; 82 ListNode* aHead = new ListNode(1); 83 ListNode* cur = aHead; 84 85 for (int i = 2; i < 10; i += 2) 86 { 87 ListNode* tmpLN = new ListNode(i); 88 cur->next = tmpLN; 89 cur = tmpLN; 90 } 91 92 // testSolution.PrintListNode(aHead); 93 94 ListNode* bHead = new ListNode(1); 95 cur = bHead; 96 97 for (int i = 3; i < 10; i += 2) 98 { 99 ListNode* tmpLN = new ListNode(i); 100 cur->next = tmpLN; 101 cur = tmpLN; 102 } 103 104 // testSolution.PrintListNode(bHead); 105 106 ListNode* head = testSolution.MergeList(aHead, bHead); 107 108 // testSolution.PrintListNode(head); 109 110 while (head != NULL) 111 { 112 cout << head->val << endl; 113 head = head->next; 114 } 115 116 getchar(); 117 118 return 0; 119 }
3:倒序打印一个单链表;
- 递归
- 链表的题目还得多练,又弄错了打印head还是cur节点。。。
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 void PrintListNodeReversely(ListNode* inListNode) 15 { 16 if (inListNode != NULL) 17 { 18 PrintListNodeReversely(inListNode->next); 19 cout << inListNode->val << endl; 20 } 21 } 22 }; 23 24 int main () 25 { 26 Solution testSolution; 27 ListNode* head = new ListNode(0); 28 ListNode* cur = head; 29 30 for (int i = 1; i < 10; i ++) 31 { 32 ListNode* tmpLN = new ListNode(i); 33 cur->next = tmpLN; 34 cur = cur->next; // cur->next == tmpLN 35 } 36 37 // Print head node 38 testSolution.PrintListNodeReversely(head); 39 40 getchar(); 41 42 return 0; 43 }
4:给定一个单链表的头指针和一个指定节点的指针,在O(1)时间删除该节点;
- http://www.cnblogs.com/pegasus923/archive/2010/10/04/1841891.html
- 重温链表插入删除操作,注意原文代码删除头结点处有问题,函数对头指针只是值传递,如果要删除需要传入头指针的指针。
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 void PrintListNode(ListNode* inListNode) 15 { 16 if (inListNode != NULL) { 17 cout << inListNode->val << endl; 18 PrintListNode(inListNode->next); 19 } else 20 cout << endl; 21 } 22 23 void Test(ListNode* inListNode) 24 { 25 delete inListNode; 26 inListNode = NULL; 27 cout << inListNode << endl; 28 29 PrintListNode(inListNode); 30 } 31 32 void DeleteNode(ListNode* pInHead, ListNode* pToBeDeleted) 33 { 34 cout << "Entry void DeleteNode(ListNode* pInHead, ListNode* pToBeDeleted)\n" << endl; 35 36 // Check NULL always 37 if (pInHead == NULL || pToBeDeleted == NULL) 38 return; 39 40 // PrintListNode(pInHead); 41 42 // Delete non-tail node including head node 43 if (pToBeDeleted->next != NULL) { 44 ListNode* pNext = pToBeDeleted->next; 45 pToBeDeleted->val = pNext->val; 46 pToBeDeleted->next = pNext->next; 47 48 delete pNext; 49 pNext = NULL; 50 } else { // Delete tail 51 ListNode* pPre = pInHead; 52 53 while (pPre->next != pToBeDeleted && pPre != NULL) 54 pPre = pPre->next; 55 56 if (pPre == NULL) 57 return; 58 59 pPre->next = NULL; 60 delete pToBeDeleted; 61 pToBeDeleted = NULL; 62 } 63 } 64 }; 65 66 int main () 67 { 68 Solution testSolution; 69 int count = 5; 70 71 for (int k = 0; k <= count; k ++) 72 { 73 ListNode* pHead = NULL; 74 ListNode* pCur = NULL; 75 ListNode* pDel = NULL; 76 77 for (int i = 0; i < count; i ++) 78 { 79 ListNode* pTemp = new ListNode(i); 80 81 if (i == 0) 82 pHead = pCur = pTemp; 83 else { 84 pCur->next = pTemp; 85 pCur = pCur->next; // pCur->next == pTemp 86 } 87 88 if (i == k) 89 pDel = pTemp; 90 } 91 92 cout << "pHead = " << pHead << endl; 93 if (pHead != NULL) 94 cout << "pHead->val = " << pHead->val << endl; 95 cout << "pDel = " << pDel << endl; 96 if (pDel != NULL) 97 cout << "pDel->val = " << pDel->val << endl; 98 cout << ((pHead == pDel) ? "pHead == pDel" : "pHead != pDel") << endl; 99 cout << endl; 100 101 // Print Linkedlist 102 testSolution.PrintListNode(pHead); 103 104 testSolution.DeleteNode(pHead, pDel); 105 // testSolution.Test(pHead); 106 107 /* 108 delete pDel; 109 pDel = NULL; 110 pHead = NULL; 111 */ 112 cout << "pHead = " << pHead << endl; 113 if (pHead != NULL) 114 cout << "pHead->val = " << pHead->val << endl; 115 cout << "pDel = " << pDel << endl; 116 if (pDel != NULL) 117 cout << "pDel->val = " << pDel->val << endl; 118 cout << endl; 119 120 // Print Linkedlist 121 testSolution.PrintListNode(pHead); 122 } 123 124 getchar(); 125 126 return 0; 127 }
5:找到链表倒数第K个节点; K=0时,返回链表尾元素。
- 两个指针同时往后走,之间相隔K个元素。一个到达尾部时,另一个正好为倒数第K个。
- 注意边界情况,头指针为NULL,K为0,K大于链表长度。
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 void PrintListNode(ListNode* inListNode) 15 { 16 if (inListNode != NULL) { 17 cout << inListNode->val << endl; 18 PrintListNode(inListNode->next); 19 } else 20 cout << endl; 21 } 22 23 ListNode *findMToLastElement(ListNode* pInHead, int m) 24 { 25 cout << "Entry ListNode *findMToLastElement(ListNode* pInHead, int m)\n" << endl; 26 27 ListNode *pCur = NULL, *pMPre = NULL; 28 29 // Corner case 30 if (pInHead == NULL) return NULL; 31 32 pCur = pMPre = pInHead; 33 34 // Move pCur forward m elements 35 for (int i = 0; i < m; i ++) 36 { 37 if (pCur->next != NULL) 38 pCur = pCur->next; 39 else 40 return NULL; 41 } 42 43 // Move forward together until pCur reach the tail 44 while (pCur->next != NULL) 45 { 46 pCur = pCur->next; 47 pMPre = pMPre->next; 48 } 49 50 // Now pMPre points to the M to last element 51 return pMPre; 52 } 53 }; 54 55 int main () 56 { 57 Solution testSolution; 58 int count = 10; 59 60 ListNode *pHead = NULL; 61 ListNode *pCur = NULL; 62 63 for (int i = 0; i < count; i ++) 64 { 65 ListNode *pTemp = new ListNode(i); 66 67 if (i == 0) 68 pHead = pCur = pTemp; 69 else { 70 pCur->next = pTemp; 71 pCur = pCur->next; // pCur->next == pTemp 72 } 73 } 74 75 // Print Head 76 cout << "pHead = " << pHead << endl; 77 if (pHead != NULL) 78 cout << "pHead->val = " << pHead->val << endl; 79 cout << endl; 80 81 // Print Linkedlist 82 cout << "PrintListNode(pHead)" << endl; 83 testSolution.PrintListNode(pHead); 84 85 cout << "Test findMToLastElement(pHead, 0)\n" << endl; 86 ListNode *pMToLastElement = testSolution.findMToLastElement(pHead, 0); 87 88 // Print Head 89 cout << "pHead = " << pHead << endl; 90 if (pHead != NULL) 91 cout << "pHead->val = " << pHead->val << endl; 92 cout << endl; 93 94 // Print M to last element 95 cout << "pMToLastElement = " << pMToLastElement << endl; 96 if (pMToLastElement != NULL) 97 cout << "pMToLastElement->val = " << pMToLastElement->val << endl; 98 cout << endl; 99 100 getchar(); 101 102 return 0; 103 }
6:反转单链表;
- 注意保留反转时,先保留next指针地址,反转之后再赋值给current指针往后走,否则丢了next指针。
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x = 0) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 void PrintList(ListNode *inListNode) 15 { 16 if (inListNode != NULL) { 17 cout << inListNode->val << endl; 18 PrintList(inListNode->next); 19 } else 20 cout << "NULL\n" << endl; 21 } 22 23 // Assign in ptr of the head ptr 24 void DeleteList(ListNode **pInHead) 25 { 26 cout << "Entry void DeleteList(ListNode **pInHead)\n" << endl; 27 28 ListNode *pDel = *pInHead; 29 30 while (pDel != NULL) 31 { 32 // Reserve the address of the next node 33 ListNode *pNext = pDel->next; 34 // Delete the current node 35 delete pDel; 36 pDel = NULL; 37 // Move to the next node 38 pDel = pNext; 39 } 40 41 // Set head to NULL 42 *pInHead = NULL; 43 } 44 45 ListNode* ReverseList(ListNode* pHead) 46 { 47 cout << "Entry ListNode* ReverseList(ListNode* pHead)\n" << endl; 48 49 // Corner case 50 if (pHead == NULL) return NULL; 51 52 ListNode *pPre = NULL, *pRHead = NULL, *pCur = pHead; 53 54 while (pCur != NULL) 55 { 56 // Reserve the next node 57 ListNode *pNext = pCur->next; 58 // Reserve the address of the last node of original list 59 if (pNext == NULL) pRHead = pCur; 60 // Insert current node 61 pCur->next = pPre; 62 // Move the previous ptr 63 pPre = pCur; 64 // Assign the next node back 65 pCur = pNext; 66 } 67 68 return pRHead; 69 } 70 }; 71 72 int main () 73 { 74 Solution testSolution; 75 int count = 10; 76 77 ListNode *pMHead = NULL; 78 ListNode *pMCur = NULL; 79 80 for (int i = 0; i < count; i ++) 81 { 82 ListNode *pTemp = new ListNode(i); 83 84 if (i == 0) 85 pMHead = pMCur = pTemp; 86 else { 87 pMCur->next = pTemp; 88 pMCur = pMCur->next; // pCur->next == pTemp 89 } 90 } 91 92 // Print Head 93 cout << "pMHead = " << pMHead << endl; 94 if (pMHead != NULL) 95 cout << "pMHead->val = " << pMHead->val << endl; 96 cout << endl; 97 98 // Print Linkedlist 99 cout << "PrintList(pMHead)" << endl; 100 testSolution.PrintList(pMHead); 101 102 cout << "Test ReverseList(pMHead)\n" << endl; 103 ListNode *pMRHead = testSolution.ReverseList(pMHead); 104 105 // Print Reversed Head 106 cout << "pMRHead = " << pMRHead << endl; 107 if (pMRHead != NULL) 108 cout << "pMRHead->val = " << pMRHead->val << endl; 109 cout << endl; 110 111 // Print Linkedlist 112 cout << "PrintList(pMRHead)" << endl; 113 testSolution.PrintList(pMRHead); 114 115 // Print Head 116 cout << "pMHead = " << pMHead << endl; 117 if (pMHead != NULL) 118 cout << "pMHead->val = " << pMHead->val << endl; 119 cout << endl; 120 121 // Print Linkedlist 122 cout << "PrintList(pMHead)" << endl; 123 testSolution.PrintList(pMHead); 124 125 cout << "DeleteList(&pMRHead)" << endl; 126 testSolution.DeleteList(&pMRHead); 127 128 // Print Reversed Head 129 cout << "pMRHead = " << pMRHead << endl; 130 if (pMRHead != NULL) 131 cout << "pMRHead->val = " << pMRHead->val << endl; 132 cout << endl; 133 134 // Print Linkedlist 135 cout << "PrintList(pMRHead)" << endl; 136 testSolution.PrintList(pMRHead); 137 138 // Print Head 139 cout << "pMHead = " << pMHead << endl; // It is not NULL, the space is free'ed? 140 if (pMHead != NULL) 141 cout << "pMHead->val = " << pMHead->val << endl; 142 cout << endl; 143 144 // Print Linkedlist 145 // cout << "PrintList(pMHead)" << endl; 146 // testSolution.PrintList(pMHead); 147 148 getchar(); 149 150 return 0; 151 }
7:通过两个栈实现一个队列;
- stack 类
- https://msdn.microsoft.com/zh-cn/library/56fa1zk5.aspx
- stack - C++ Reference
- http://www.cplusplus.com/reference/stack/stack/
- Stack_百度百科
- http://baike.baidu.com/link?url=umZEKUINQtIeQve3VZ9u7eJSI2IvARxNaxZus-XwejEcV2QSUjgD-qNQS-efMtjl_96xGF_LXYyUuGO0-ewAzq#5
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 class Solution 6 { 7 public: 8 void push(int node) 9 { 10 stack1.push(node); 11 } 12 13 int pop() 14 { 15 int result = 0; 16 17 if (stack2.empty()) 18 { 19 while (!stack1.empty()) 20 { 21 stack2.push(stack1.top()); 22 stack1.pop(); 23 } 24 } 25 26 result = stack2.top(); 27 stack2.pop(); 28 29 return result; 30 } 31 32 private: 33 stack<int> stack1; 34 stack<int> stack2; 35 }; 36 37 int main () 38 { 39 Solution testSolution; 40 int count = 10; 41 42 // Case 1 43 cout << "CASE 1\n" << endl; 44 45 for (int i = 0; i < count; i ++) 46 { 47 testSolution.push(i); 48 } 49 50 for (int i = 0; i < count; i ++) 51 { 52 cout << testSolution.pop() << endl; 53 } 54 55 // Case 2 56 cout << "\nCASE 2\n" << endl; 57 58 for (int i = 0; i < count; i ++) 59 { 60 testSolution.push(i); 61 cout << testSolution.pop() << endl; 62 } 63 64 // Case 3 65 cout << "\nCASE 3\n" << endl; 66 67 for (int i = 0; i < count / 2; i ++) 68 { 69 testSolution.push(i); 70 } 71 72 cout << testSolution.pop() << "\n" << endl; 73 74 for (int i = count / 2; i < count; i ++) 75 { 76 testSolution.push(i); 77 } 78 79 for (int i = 0; i < count - 1; i ++) 80 { 81 cout << testSolution.pop() << endl; 82 } 83 84 getchar(); 85 86 return 0; 87 }
8:二分查找;
- 用vector实现递归和非递归二分查找。刚开始没弄清元素个数,初始化1个元素,再push_back n-1个元素,这时vector里应该是n个元素。
- iterator作为入参传递有问题,先用int代替了,以后再研究
- 用distance来计算找到的当前元素是第几个元素
- vector的二分查找算法 - 轻典 - 博客园
- http://www.cnblogs.com/tianyajuanke/archive/2012/05/23/2515117.html
- distance - C++ Reference
- http://www.cplusplus.com/reference/iterator/distance/
- distance
- https://msdn.microsoft.com/zh-cn/library/k1kfxk7e.aspx
1 #include <iostream> 2 #include <vector> 3 #include <iterator> 4 using namespace std; 5 6 class Solution 7 { 8 public: 9 int binarySearch(vector<int> array, int target) 10 { 11 vector<int>::iterator vecBIT = array.begin(); 12 vector<int>::iterator vecEIT = array.end(); 13 vector<int>::iterator vecIT = vecBIT + (vecEIT - vecBIT) / 2; 14 15 while (vecBIT <= vecEIT) 16 { 17 if (*vecIT == target) 18 return distance(array.begin(), vecIT); // Return distance between iterators 19 else if (*vecIT < target) 20 { 21 vecBIT = vecIT + 1; 22 vecIT = vecBIT + (vecEIT - vecBIT) / 2; 23 } 24 else 25 { 26 vecEIT = vecIT - 1; 27 vecIT = vecBIT + (vecEIT - vecBIT) / 2; 28 } 29 } 30 31 if (vecBIT > vecEIT) return -1; 32 } 33 34 int binarySearchRecursion(vector<int> array, int vecBIT, int vecEIT, int target) 35 { 36 // cout << "Entry int binarySearchRecursion(vector<int> array, vector<int>::iterator vecBIT, vector<int>::iterator vecEIT, int target)\n" << endl; 37 38 if (vecBIT <= vecEIT) 39 { 40 int vecIT = vecBIT + (vecEIT - vecBIT) / 2; 41 42 if (array[vecIT] == target) 43 return vecIT; 44 else if (array[vecIT] < target) 45 return binarySearchRecursion(array, vecIT + 1, vecEIT, target); 46 else 47 return binarySearchRecursion(array, vecBIT, vecIT - 1, target); 48 } 49 else 50 return -1; 51 } 52 }; 53 54 int main () 55 { 56 Solution testSolution; 57 int n = 3; 58 vector<int> searchArray(1); // initialize vector of n elements with 0 59 60 // push_back another n - 1 elements 61 for (int i = 1; i < n; i ++) 62 searchArray.push_back(i); 63 64 // n element in vector now 65 for (vector<int>::const_iterator vecIT = searchArray.begin(); vecIT < searchArray.end(); vecIT ++) 66 cout << *vecIT << endl; 67 cout << endl; 68 69 cout << distance(searchArray.begin(), searchArray.end()) << "\n" << endl; 70 71 for (int i = 0; i <= n; i ++) 72 { 73 cout << testSolution.binarySearch(searchArray, i) << endl; 74 cout << testSolution.binarySearchRecursion(searchArray, 0, n, i) << endl; 75 } 76 77 getchar(); 78 79 return 0; 80 }
9:快速排序;
- 注意对vector入参要用引用,不能用形参,否则对vector元素排序不起作用
- vector有序情况下,快排时间复杂度最高退化为O(N^2)
- 输出vector也可以使用范围for语句
- for (auto vecCIT : vecArray) cout << vecCIT << endl;
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 class Solution 6 { 7 public: 8 // Pass in reference of vector parameter 9 void quickSort(vector<int> &a, int inLeft, int inRight) 10 { 11 cout << "Entry void qSort(vector<int> array, int left, int right)\n" << endl; 12 13 if (inLeft >= inRight) 14 return; 15 16 int i = inLeft, j = inRight, temp = a[inLeft]; 17 18 while (i < j) 19 { 20 // Scan from right to left 21 while ((i < j) && (a[j] >= temp)) 22 j --; 23 if (i < j) 24 a[i ++] = a[j]; 25 26 // Scan from left to right 27 while ((i < j) && (a[i] <= temp)) 28 i ++; 29 if (i < j) 30 a[j --] = a[i]; 31 } 32 // Base value temp is on the right position 33 a[i] = temp; 34 35 // Divide and conquer 36 quickSort(a, inLeft, i - 1); 37 quickSort(a, i + 1, inRight); 38 } 39 }; 40 41 int main () 42 { 43 Solution testSolution; 44 int array[] = {0, 1, 5, 9, 0, 2, 6, 7, 8, 3, 4}; 45 // int array[] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 46 // int array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0}; 47 // int array[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; 48 vector<int> vecArray(array, array + 11); 49 50 for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++) 51 cout << *vecCIT << endl; 52 cout << endl; 53 54 testSolution.quickSort(vecArray, 0, vecArray.size() - 1); 55 56 for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++) 57 cout << *vecCIT << endl; 58 cout << endl; 59 60 getchar(); 61 62 return 0; 63 }
10:获得一个int型的数中二进制中1的个数; 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 位运算
- 如果不是负数的话,可以一直右移获取1的个数,f(n) = f(n / 2) + n % 2。跟LeetCode 338 Counting Bits一样。
- http://www.cnblogs.com/pegasus923/p/5499737.html
- 负数用补码表示。所以只能用n = n & (n - 1),用n跟n-1做&运算,把二进制中的1从后往前去掉,直到没有。注意2的幂的特征(n & (n - 1)) == 0,e.g. 0x1000 & 0x0111。
- 补码_百度百科
- http://baike.baidu.com/link?url=ITDahaDRGLVt2jyxtz0t3a7DbXYFBk1kVZMxzX7SsmxRnTpPBYKHCBYM2zFs1t3s6FrDlgFoYqtTZnnbWClt6a
1 #include <iostream> 2 using namespace std; 3 4 class Solution 5 { 6 public: 7 int NumberOf1(int n) 8 { 9 cout << "Entry int NumberOf1(int n)\n" << endl; 10 11 if (n == 0) return 0; 12 13 int count = 0; 14 15 while (n != 0) 16 { 17 n = n & (n - 1); 18 count ++; 19 } 20 21 return count; 22 } 23 }; 24 25 int main () 26 { 27 Solution testSolution; 28 int n = 10; 29 30 for (int i = 0; i < n; i ++) 31 cout << testSolution.NumberOf1(i) << endl; 32 33 getchar(); 34 35 return 0; 36 }
11:输入一个数组,实现一个函数,让所有奇数都在偶数前面; 并保证奇数和奇数,偶数和偶数之间的相对位置不变。
- 跟排序思想差不多。原文的思想类似快排,两个指针一个从头往后找偶数,另一个从尾往前找奇数,找到就交换,直到两个指针相遇。但这个是不稳定的,所以奇偶数之间的相对位置会变。可以用归并,冒泡排序思想,这些都是稳定的。
- 另一种解法就是借助辅助vector存储偶数,扫描一遍把偶数挑出来并从原vector删除,之后再push_back回去。
- 注意vector.end()并不是最后一个元素,而是vector结束符。要找最后一个元素的下标是vector.end()-1。
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 class Solution 6 { 7 public: 8 void reOrderArray(vector<int> &array) 9 { 10 cout << "Entry void reOrderArray(vector<int> &array)\n" << endl; 11 12 vector<int> vecEven; // Store even 13 14 for (vector<int>::iterator vecIT = array.begin(); vecIT != array.end(); ) 15 if ((*vecIT % 2) == 0) 16 { 17 vecEven.push_back(*vecIT); 18 vecIT = array.erase(vecIT); 19 } 20 else 21 vecIT ++; 22 23 for (vector<int>::const_iterator vecCIT = vecEven.begin(); vecCIT != vecEven.end(); vecCIT ++) 24 array.push_back(*vecCIT); 25 } 26 }; 27 28 int main () 29 { 30 Solution testSolution; 31 int array[] = {0, 1, 5, 9, 2, 6, 7, 8, 3, 4}; 32 vector<int> vecArray(array, array + 10); 33 34 for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++) 35 cout << *vecCIT << endl; 36 cout << endl; 37 38 testSolution.reOrderArray(vecArray); 39 40 for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++) 41 cout << *vecCIT << endl; 42 cout << endl; 43 44 getchar(); 45 46 return 0; 47 }
12:判断一个字符串是否是另一个字符串的子串;
- 简单的暴力匹配。关键是熟悉string函数,不出BUG。
- kmp算法_百度百科
- http://baike.baidu.com/view/659777.htm
- 字符串匹配的KMP算法_知识库_博客园
- http://kb.cnblogs.com/page/176818/
- 字符串匹配的Boyer-Moore算法_知识库_博客园
- http://kb.cnblogs.com/page/176945/
- KMP算法详解
- http://www.matrix67.com/blog/archives/115
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Solution { 6 public: 7 int substr(const string source, const string sub) 8 { 9 // Corner case 10 if (sub.empty()) return 0; 11 if (source.empty()) return -1; 12 13 int n = source.length() - sub.length() + 1; 14 15 // better use < rather than <= 16 for (int i = 0; i < n; i ++) 17 { 18 bool flag = true; 19 20 for (int j = 0; j < sub.length(); j ++) 21 { 22 if (source.at(i + j) != sub.at(j)) 23 { 24 flag = false; 25 break; 26 } 27 } 28 29 if (flag) return i; 30 } 31 32 return -1; 33 } 34 }; 35 36 int main () 37 { 38 Solution testSolution; 39 string s1 = "mississippi"; 40 string s2 = "issi"; 41 42 cout << testSolution.substr(s1, s2) << endl; 43 44 getchar(); 45 46 return 0; 47 }
13:把一个int型数组中的数字拼成一个串,这个串代表的数字最小;
- 把数组转成字符串然后进行升序排序,定义如果AB < BA,那么A < B。排序完成,再把数组组合就成了最小串了。
- 学习了sort的比较函数的写法。注意类中自定义的compare需要定义成static,否则sort函数编译出错。
- 学习了int跟string转换的几种方法,to_string方便只是是C++11的。
- sort - C++ Reference
- http://www.cplusplus.com/reference/algorithm/sort/?kw=sort
- sort
- https://msdn.microsoft.com/zh-cn/library/ecdecxh1(v=vs.110).aspx
- STL 中sort、qsort 的用法 - rattles的专栏 - 博客频道 - CSDN.NET
- http://blog.csdn.net/rattles/article/details/5510919
- C++中Static作用和使用方法
- http://blog.csdn.net/artechtor/article/details/2312766
- sprintf - C++ Reference
- http://www.cplusplus.com/reference/cstdio/sprintf/
- sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_l
- https://msdn.microsoft.com/zh-cn/library/ybk95axf.aspx
- to_string - C++ Reference
- http://www.cplusplus.com/reference/string/to_string/
- C++ int与string的转化 - Andy Niu - 博客园
- http://www.cnblogs.com/nzbbody/p/3504199.html
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> // sprintf 4 #include <algorithm> // sort 5 using namespace std; 6 7 class Solution 8 { 9 public: 10 // Need to define static 11 static bool compare(const string &sA, const string &sB) 12 { 13 string sAB = sA + sB; 14 string sBA = sB + sA; 15 16 return sAB < sBA; 17 } 18 19 string PrintMinNumber(vector<int> numbers) 20 { 21 cout << "Entry string PrintMinNumber(vector<int> numbers)\n" << endl; 22 23 string result = ""; 24 25 // Corner case 26 if (numbers.size() == 0) return result; 27 28 vector<string> sNumbers; 29 char *sTemp = new char[10]; // Remember to initialize ptr 30 31 for (vector<int>::const_iterator vecCIT = numbers.begin(); vecCIT != numbers.end(); vecCIT ++) 32 { 33 // string sTemp = to_string(*vecCIT); // C++11 34 sprintf(sTemp, "%d", *vecCIT); 35 sNumbers.push_back(sTemp); 36 } 37 38 // Use self-defined compare function 39 sort(sNumbers.begin(), sNumbers.end(), compare); 40 41 for (vector<string>::const_iterator vecCIT = sNumbers.begin(); vecCIT != sNumbers.end(); vecCIT ++) 42 result += *vecCIT; 43 44 return result; 45 } 46 }; 47 48 int main () 49 { 50 Solution testSolution; 51 int array[] = {3, 32, 321}; 52 vector<int> vecArray(array, array + 3); 53 // vector<int> vecArray; 54 55 for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++) 56 cout << *vecCIT << endl; 57 cout << endl; 58 59 cout << testSolution.PrintMinNumber(vecArray) << endl; 60 61 getchar(); 62 63 return 0; 64 }
14:输入一颗二叉树,输出它的镜像(每个节点的左右子节点交换位置);
- 交换左右子节点(注意是节点,不只是值),然后递归处理左右子树。
- 复习了建树过程。
- swap - C++ Reference
- http://www.cplusplus.com/reference/utility/swap/?kw=swap
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 struct TreeNode { 6 int val; 7 struct TreeNode *left; 8 struct TreeNode *right; 9 TreeNode(int x) : 10 val(x), left(NULL), right(NULL) { 11 } 12 }; 13 14 class Solution 15 { 16 public: 17 TreeNode* CreateTree(const vector<int> &vec, const int &pos) 18 { 19 // cout << "Entry TreeNode* CreateTree(const vector<int> &vec, const int &pos)\n" << endl; 20 21 // cout << "pos = " << pos << endl; 22 // cout << "vec.size() = " << vec.size() << endl; 23 24 // Pay attention to >=, or else infinite loop 25 if (pos >= vec.size()) return NULL; 26 27 // cout << "vec[pos] = " << vec[pos] << endl; 28 29 TreeNode *pCur = new TreeNode(vec[pos]); 30 // cout << "pCur->val = " << pCur->val<< endl; 31 pCur->left = CreateTree(vec, 2 * pos); 32 pCur->right = CreateTree(vec, 2 * pos + 1); 33 34 return pCur; 35 } 36 37 void PrintTree(TreeNode *pTreeNode) 38 { 39 if (pTreeNode != NULL) { 40 cout << pTreeNode->val << endl; 41 PrintTree(pTreeNode->left); 42 PrintTree(pTreeNode->right); 43 } 44 } 45 46 void Mirror(TreeNode *pRoot) 47 { 48 // cout << "Entry void Mirror(TreeNode *pRoot) " << endl; 49 50 // Corner case 51 if ((pRoot == NULL) || ((pRoot->left == NULL) && (pRoot->right == NULL))) return; 52 53 // swap two ptr rathet than value 54 swap(pRoot->left, pRoot->right); 55 56 Mirror(pRoot->left); 57 Mirror(pRoot->right); 58 } 59 }; 60 61 int main () 62 { 63 Solution testSolution; 64 int count = 8; 65 int array[] = {0, 8, 6, 10, 5, 7, 9, 11}; 66 vector<int> vecArray(array, array + count); 67 68 TreeNode *pMRoot = testSolution.CreateTree(vecArray, 1); 69 /* 70 cout << root << endl; 71 cout << root->val << endl; 72 */ 73 testSolution.PrintTree(pMRoot); 74 cout << endl; 75 76 testSolution.Mirror(pMRoot); 77 78 testSolution.PrintTree(pMRoot); 79 cout << endl; 80 81 getchar(); 82 83 return 0; 84 }
15:输入两个链表,找到它们第一个公共节点;
- 若有公共节点,则从公共节点之后的所有节点都是公共的。I.e. 短链表是长链表的子串。基于这个思想,长链表里的公共节点只可能出现在倒数K个节点里(K为短链表长度)。长链表先走N-K步,长度相同时再开始往后挨个找。
1 #include <iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int val; 7 ListNode *next; 8 ListNode(int x = 0) : val(x), next(NULL) {} 9 }; 10 11 class Solution 12 { 13 public: 14 void PrintList(ListNode *pListNode) 15 { 16 if (pListNode != NULL) { 17 cout << pListNode->val << endl; 18 PrintList(pListNode->next); 19 } else 20 cout << "NULL\n" << endl; 21 } 22 23 int getLengthOfList(const ListNode *pListNode) 24 { 25 int length = 0; 26 27 while (pListNode != NULL) 28 { 29 pListNode = pListNode->next; 30 length ++; 31 } 32 33 return length; 34 } 35 36 ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2) 37 { 38 // cout << "Entry ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)" << endl; 39 40 int len1 = getLengthOfList(pHead1); 41 int len2 = getLengthOfList(pHead2); 42 43 if (len1 > len2) 44 { 45 int gap = len1 - len2; 46 for (int i = 0; i < gap; i ++) 47 pHead1 = pHead1->next; 48 } 49 else 50 { 51 int gap = len2 - len1; 52 for (int i = 0; i < gap; i ++) 53 pHead2 = pHead2->next; 54 } 55 56 while ((pHead1 != NULL) && (pHead2 != NULL) && (pHead1 != pHead2)) 57 { 58 pHead1 = pHead1->next; 59 pHead2 = pHead2->next; 60 } 61 62 return pHead1; 63 } 64 }; 65 66 int main () 67 { 68 Solution testSolution; 69 int count = 10, k = 0; 70 71 ListNode *pMHead = NULL; 72 ListNode *pMCur = NULL; 73 ListNode *pKNode = NULL; 74 75 for (int i = 0; i < count; i ++) 76 { 77 ListNode *pTemp = new ListNode(i); 78 79 if (i == 0) 80 pMHead = pMCur = pTemp; 81 else { 82 pMCur->next = pTemp; 83 pMCur = pMCur->next; // pMCur->next == pTemp 84 } 85 86 if (i == k) 87 pKNode = pMCur; 88 } 89 90 // Print Head 91 cout << "pMHead = " << pMHead << endl; 92 if (pMHead != NULL) 93 cout << "pMHead->val = " << pMHead->val << endl; 94 cout << endl; 95 96 // Print Kth Node 97 cout << "pKNode = " << pKNode << endl; 98 if (pKNode != NULL) 99 cout << "pKNode->val = " << pKNode->val << endl; 100 cout << endl; 101 102 // Print Linkedlist 103 cout << "PrintList(pMHead)" << endl; 104 testSolution.PrintList(pMHead); 105 106 ListNode *pTarget = testSolution.FindFirstCommonNode(pMHead, pKNode); 107 108 // Print Head 109 cout << "pMHead = " << pMHead << endl; 110 if (pMHead != NULL) 111 cout << "pMHead->val = " << pMHead->val << endl; 112 cout << endl; 113 114 // Print Kth Node 115 cout << "pTarget = " << pTarget << endl; 116 if (pTarget != NULL) 117 cout << "pTarget->val = " << pTarget->val << endl; 118 cout << endl; 119 120 // Print Linkedlist 121 cout << "PrintList(pMHead)" << endl; 122 testSolution.PrintList(pMHead); 123 124 getchar(); 125 126 return 0; 127 }