38. 数字 k 在有序数组中出现的次数
二分查找:找出第一个 k 和最后一个 k 。
#include <iostream> using namespace std; int getFirstOfK(int data[], int length, int k, int low, int high) { if(low <= high) { int mid = (low + high) / 2; if(data[mid] == k && (mid == 0 || data[mid-1] != k)) return mid; else if(data[mid] < k) low = mid + 1; else high = mid - 1; return getFirstOfK(data, length, k, low, high); } return -1; } int getLastOfK(int data[], int length, int k, int low, int high) { if(low <= high) { int mid = (low + high) / 2; if(data[mid] == k && (mid == length-1 || data[mid+1] != k)) return mid; else if(data[mid] > k) high = mid - 1; else low = mid + 1; return getLastOfK(data, length, k, low, high); } return -1; } int getNumberOfK(int data[], int length, int k) { int count = 0; if(data != NULL && length > 0) { int first = getFirstOfK(data, length, k, 0, length-1); if(first == -1) return -1; int last = getLastOfK(data, length, k, first, length-1); count = last - first + 1; } return count; } int main() { int data[] = {1, 2, 3, 3, 3, 3, 4, 5}; cout << getNumberOfK(data, sizeof(data)/4, 3) << endl; cout << getNumberOfK(data, sizeof(data)/4, 1) << endl; cout << getNumberOfK(data, sizeof(data)/4, 2) << endl; cout << getNumberOfK(data, sizeof(data)/4, 5) << endl; return 0; }
39. 二叉树的深度 && 平衡二叉树的判断 && 二叉树结点的最大距离(题目来自编程之美,解法自创)
note:三种算法都必须是后序遍历。
#include <iostream> #include <string> using namespace std; typedef struct BTNode { int v; // default positive Integer. BTNode *pLeft; BTNode *pRight; BTNode(int x) : v(x), pLeft(NULL), pRight(NULL) {} } BinaryTree; /********************************************************/ /***** Basic functions ***********/ BinaryTree* createBinaryTree() // input a preOrder traversal sequence, 0 denote empty node. { BTNode *pRoot = NULL; int r; cin >> r; if(r != 0) // equal to if(!r) return; { pRoot = new BTNode(r); pRoot->pLeft = createBinaryTree(); pRoot->pRight = createBinaryTree(); } return pRoot; } void release(BinaryTree *root){ if(root == NULL) return; release(root->pLeft); release(root->pRight); delete[] root; root = NULL; } void print(BinaryTree *root, int level = 1){ if(root == NULL) { cout << "NULL"; return; }; string s; for(int i = 0; i < level; ++i) s += " "; cout << root->v << endl << s; print(root->pLeft, level+1); cout << endl << s; print(root->pRight, level+1); } /******************************************************************/ int getDepth(BinaryTree *root) // leaf Node is at depth 1 { if(root == NULL) return 0; int leftDepth = getDepth(root->pLeft); int rightDepth = getDepth(root->pRight); return 1 + (leftDepth > rightDepth ? leftDepth : rightDepth); } bool isBalanced(BinaryTree *root, int *depth) // must be postOrder traversal { if(root == NULL) { *depth = 0; return true; }; int leftDepth, rightDepth; if(isBalanced(root->pLeft, &leftDepth) && isBalanced(root->pRight, &rightDepth)) { *depth = 1 + (leftDepth > rightDepth ? leftDepth : rightDepth); if(leftDepth - rightDepth >= -1 && leftDepth - rightDepth <= 1) return true; else return false; } } bool isBalanced(BinaryTree *root) { int depth; return isBalanced(root, &depth); } int getMaxDistance(BinaryTree *root, int *maxDistance) // leaf node depth is set to 0 { if(root == NULL) return -1; int leftDepth = getMaxDistance(root->pLeft, maxDistance); int rightDepth = getMaxDistance(root->pRight, maxDistance); if(*maxDistance < 2 + leftDepth + rightDepth) *maxDistance = 2 + leftDepth + rightDepth; return 1 + (leftDepth > rightDepth ? leftDepth : rightDepth); } int getMaxDistance(BinaryTree *root) { int maxDistance = 0; getMaxDistance(root, &maxDistance); return maxDistance; } int main(){ int TestTime = 3, k = 1; while(k <= TestTime) { cout << "Test " << k++ << ":" << endl; cout << "Create a tree: " << endl; BinaryTree *pRoot = createBinaryTree(); print(pRoot); cout << endl; cout << "The depth of binary tree: " << getDepth(pRoot) << endl; if(isBalanced(pRoot)) cout << "Does the tree is a balanced binary tree ? true" << endl; else cout << "Does the tree is a balanced binary tree ? false" << endl; cout << "The max distance between two nodes: " << getMaxDistance(pRoot) << endl; release(pRoot); } return 0; }
40. 数组中只出现一次的数字
首先, 参考 Link: Single Number
其次,数组中有两个只出现一次的数字时: 例:{2,4,3,6,3,2,5,5}
#include <iostream> using namespace std; void findTwoNumbers(int data[], int length, int *num1, int *num2) { if(data == NULL || length < 2) return; int total = 0; for(int i = 0; i < length; ++i) total ^= data[i]; int shift1 = 1; for(int i = 0; i < sizeof(int)*8; ++i) { total >>= 1; shift1 <<= 1; if(total & 1) break; } *num1 = *num2 = 0; for(int i = 0; i < length; ++i) { if(data[i] & shift1) *num1 ^= data[i]; else *num2 ^= data[i]; } } int main(){ int num1, num2; int test1[8] = { 2, 4, 3, 6, 3, 2, 5, 5}; findTwoNumbers(test1, 8, &num1, &num2); cout << num1 << " "<< num2 << endl; return 0; }
41. 和为 S 的连续正数序列。
#include <iostream> using namespace std; void numsSumToS(int S) { int low = 1, high = 2; while(low < high) { int curSum = 0; for(int i = low; i <= high; ++i) curSum += i; if(curSum < S) ++high; else if(curSum > S) ++low; else { for(int i = low; i <= high; ++i) cout << i << '\t'; cout << endl; ++high; } } } int main(){ int S; while(true) { cout << "cin >> "; cin >> S; numsSumToS(S); } return 0; }
42. 翻转单词顺序 && 字符串左旋转
note:左旋转 k 位相当于右旋转 N – k 位, N 为字符串长度。