├── _config.yml ├── code ├── README.md ├── 8.斐波那契数列.cpp ├── 4.从尾到头打印链表.cpp ├── 13.二进制中1的个数.cpp ├── 40.连续子数组的最大和.cpp ├── 41.整数中1出现的次数.cpp ├── 20.链表中倒数第k个结点.cpp ├── 53.二叉树的深度.cpp ├── 44.把数字翻译成字符串.cpp ├── 56.翻转字符串.cpp ├── 19.调整数组顺序使奇数位于偶数前面.cpp ├── 14.数值的整数次方.cpp ├── 52.二叉搜索树的第k大节点.cpp ├── 9.旋转数组的最小数字.cpp ├── 28.包含min函数的栈.cpp ├── 48.第一个只出现一次的字符.cpp ├── 22.反转链表.cpp ├── 15.打印1到最大的n位数.cpp ├── 7.用两个栈实现队列.cpp ├── 25.二叉树镜像.cpp ├── 29.栈的压入弹出序列.cpp ├── 55.和为s的数字.cpp ├── 46.最长不含重复字符的子字符串.cpp ├── 30.从上到下打印二叉树.cpp ├── 26.对称的二叉树.cpp ├── 1.数组中重复的数字.cpp ├── 37.出现次数超过一半的数字.cpp ├── 2.二维数组中的查找.cpp ├── 3.替换空格.cpp ├── 39.数据流中的中位数.cpp ├── 45.礼物的最大价值.cpp ├── 24.树的子结构.cpp ├── 38.最小的k个数.cpp ├── 21.链表中环的入口节点.cpp ├── 23.合并两个排序的链表.cpp ├── 51.在排序数组中查找数字.cpp └── 50.两个链表的第一个公共节点.cpp ├── interpretation └── README.md └── README.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-merlot -------------------------------------------------------------------------------- /code/README.md: -------------------------------------------------------------------------------- 1 | # 代码库 2 | 3 | > 上一级目录为索引,本级目录下存放具体代码。 4 | 5 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/MIT) 6 | -------------------------------------------------------------------------------- /interpretation/README.md: -------------------------------------------------------------------------------- 1 | # 解答 2 | 3 | > 上一级目录为索引,本级目录下存放题目解答。 4 | 5 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/MIT) 6 | -------------------------------------------------------------------------------- /code/8.斐波那契数列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | 8 | int main() { 9 | int n; 10 | cin >> n; 11 | cout << count_1(n) << endl; 12 | return 0; 13 | } -------------------------------------------------------------------------------- /code/4.从尾到头打印链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void print_reverse_list(list link_list) { 8 | if (!link_list.empty()) { 9 | stack stack; 10 | for (auto it = link_list.begin(); it != link_list.end(); ++it) { 11 | stack.push(*it); 12 | } 13 | while (!stack.empty()) { 14 | cout << stack.top() << endl; 15 | stack.pop(); 16 | } 17 | } 18 | } 19 | 20 | int main() { 21 | list link_list = {1, 2, 3, 4, 5}; 22 | // print_reverse_list(link_list); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /code/13.二进制中1的个数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // 移位 6 | int count_1(int n) { 7 | int count = 0; 8 | int shift = 1; 9 | for(int i = 0; i < 32; ++i) { 10 | if(n & shift) 11 | ++count; 12 | shift = shift << 1; 13 | } 14 | return count; 15 | } 16 | 17 | // 一个数减一再与本身取与,会把最右边的1置0 18 | int count_2(int n) { 19 | int count = 1; 20 | while(n = (n & (n - 1))) { 21 | ++count; 22 | } 23 | return count; 24 | } 25 | 26 | int main() { 27 | int n; 28 | cin >> n; 29 | cout << count_1(n) << endl; 30 | cout << count_2(n) << endl; 31 | return 0; 32 | } -------------------------------------------------------------------------------- /code/40.连续子数组的最大和.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int subsum_max(int *array, int length) { 6 | if((array == nullptr) || (length <= 0)) 7 | return -INT32_MAX; 8 | int max = array[0]; 9 | for(int i = 1; i < length; ++i) { 10 | if(max >= 0) { 11 | if(array[i] >= 0) 12 | max = max + array[i]; 13 | else 14 | continue; 15 | } 16 | else 17 | max = array[i]; 18 | } 19 | return max; 20 | } 21 | 22 | int main() { 23 | int array[8] = {1, -2, 3, 10, 4, 7, 2, -5}; 24 | cout << subsum_max(array, 8); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /code/41.整数中1出现的次数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int has_1_count(int num) { 6 | int abs_num = abs(num); 7 | int count = 0; 8 | while(abs_num) { 9 | if(abs_num % 10 == 1) 10 | ++count; 11 | abs_num = abs_num /10; 12 | } 13 | return count; 14 | } 15 | 16 | int count_1(int *array, int length) { 17 | if((array == nullptr) || (length <= 0)) 18 | return -INT32_MAX; 19 | int sum = 0; 20 | for(int i = 0; i < length; ++i) 21 | sum = sum + has_1_count(array[i]); 22 | return sum; 23 | } 24 | 25 | int main() { 26 | int array[8] = {1, -12, 3, 10, 4, 7, 21, 51}; 27 | cout << count_1(array, 8); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /code/20.链表中倒数第k个结点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int the_kth_back_node(list link_list, int k) { 7 | if((!link_list.empty()) && (k <= link_list.size()) && (k > 0)) { 8 | auto it_fast = link_list.begin(); 9 | auto it_slow = link_list.begin(); 10 | while(k--) 11 | ++it_fast; 12 | while(it_fast != link_list.end()) { 13 | ++it_fast; 14 | ++it_slow; 15 | } 16 | return *it_slow; 17 | } 18 | return INT32_MAX; 19 | } 20 | 21 | int main() { 22 | int k; 23 | cin >> k; 24 | list link_list; 25 | for(int i = 1; i <= 10; ++i) 26 | link_list.push_back(i); 27 | cout << the_kth_back_node(link_list, k) << endl; 28 | return 0; 29 | } -------------------------------------------------------------------------------- /code/53.二叉树的深度.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef struct tree { 6 | int data; 7 | struct tree *left; 8 | struct tree *right; 9 | }tree; 10 | 11 | tree *create_tree() { 12 | tree *ptree = new tree; 13 | ptree->data = 0; 14 | ptree->left = nullptr; 15 | ptree->right = nullptr; 16 | return ptree; 17 | } 18 | 19 | int tree_height(tree *ptree) { 20 | if(ptree == nullptr) 21 | return 0; 22 | int left_height = tree_height(ptree->left); 23 | int right_height = tree_height(ptree->right); 24 | return (left_height > right_height) ? (left_height + 1) : (right_height + 1); 25 | } 26 | 27 | int main() { 28 | tree *ptree = create_tree(); 29 | int height = tree_height(ptree); 30 | cout << height << endl; 31 | return 0; 32 | } -------------------------------------------------------------------------------- /code/44.把数字翻译成字符串.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int to_number(string str, int i) { 7 | int dig1 = str[i] - '0'; 8 | int dig2 = str[i + 1] - '0'; 9 | return ((dig1 * 10) + dig2); 10 | } 11 | 12 | int get_count(string str) { 13 | int length = str.length(); 14 | int *counts = new int[length]; 15 | counts[length - 1] = 1; 16 | for(int i = length - 2; i >= 0; --i) { 17 | int num = to_number(str, i); 18 | if((num >= 10) && (num <= 25)) { 19 | if(i < length - 2) { 20 | counts[i] = counts[i + 1] + counts[i + 2]; 21 | continue; 22 | } 23 | } 24 | counts[i] = counts[i + 1]; 25 | } 26 | return counts[0]; 27 | } 28 | 29 | int main() { 30 | string str = "12215"; 31 | cout << get_count(str); 32 | return 0; 33 | } -------------------------------------------------------------------------------- /code/56.翻转字符串.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void str_reverse(string str){ 8 | if(str.empty()) 9 | return; 10 | int length = str.length(); 11 | stack stack; 12 | string word; 13 | for(int i = 0; i <= length; ++i) { 14 | if((str[i] == ' ') || (i == length)) { 15 | stack.push(word); 16 | word.clear(); 17 | } else { 18 | word.push_back(str[i]); 19 | } 20 | } 21 | int word_count = stack.size(); 22 | cout << word_count << " words." < 2 | 3 | using namespace std; 4 | 5 | // 双指针法 6 | void adjust_number(int *array, int length, bool (*func)(int)) { 7 | if(array == nullptr || length <=0) 8 | return; 9 | int front = 0; 10 | int rear = length - 1; 11 | while(front < rear) { 12 | while((!func(array[front])) && (front < rear)) 13 | front += 1; 14 | while((func(array[rear])) && (front < rear)) 15 | rear -= 1; 16 | int temp = array[front]; 17 | array[front++] = array[rear]; 18 | array[rear++] = temp; 19 | } 20 | for(int i = 0; i < 9; ++i) { 21 | cout << array[i] < 2 | 3 | using namespace std; 4 | 5 | // 全局变量标记错误类型 6 | bool g_invalid = false; 7 | 8 | // 浮点数0判断 9 | bool equal_zero(double base) { 10 | g_invalid = false; 11 | if((base < 0.000001) && (base > -0.000001)) 12 | return true; 13 | return false; 14 | } 15 | 16 | double exe_pow(double base, int exponent) { 17 | double num = 1.0; 18 | for(int i = 1; i <= exponent; ++i) 19 | num = num * base; 20 | return num; 21 | } 22 | 23 | double power(double base, int exponent){ 24 | // 先判断可能导致除0情况 25 | if(equal_zero(base) && (exponent < 0)) { 26 | g_invalid = true; 27 | return 0.0; 28 | } 29 | if(exponent > 0) 30 | return exe_pow(base, exponent); 31 | else 32 | // 负指数取倒数 33 | return (1.0 / exe_pow(base, exponent)); 34 | } 35 | 36 | int main() { 37 | double base; 38 | int exponent; 39 | cin >> base >>exponent; 40 | cout << power(base, exponent) << endl; 41 | return 0; 42 | } -------------------------------------------------------------------------------- /code/52.二叉搜索树的第k大节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef struct tree { 6 | int data; 7 | struct tree *left; 8 | struct tree *right; 9 | }tree; 10 | 11 | tree *create_tree() { 12 | tree *ptree = new tree; 13 | ptree->data = 0; 14 | ptree->left = nullptr; 15 | ptree->right = nullptr; 16 | return ptree; 17 | } 18 | 19 | tree *kth_node(tree *ptree, int k) { 20 | if((ptree == nullptr) || (k <= 0)) 21 | return nullptr; 22 | tree *target = nullptr; 23 | if(ptree->left != nullptr) 24 | target = kth_node(ptree->left, k); 25 | // target为空表示有节点被访问,ptree为指向的节点 26 | if(target == nullptr) { 27 | if(k == 1) 28 | target = ptree; 29 | k--; 30 | } 31 | if(ptree->right != nullptr) 32 | target = kth_node(ptree->right, k); 33 | return target; 34 | } 35 | 36 | int main() { 37 | int k; 38 | cin >> k; 39 | tree *ptree = create_tree(); 40 | tree *p_kth_node = kth_node(ptree, k); 41 | cout << p_kth_node->data << endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /code/9.旋转数组的最小数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 顺序遍历 7 | int find_one_by_one(int *arr, int length) { 8 | int min = INT32_MAX; 9 | if((arr != nullptr) && (length > 0)) { 10 | for(int i = 0; i < length; ++i) { 11 | if(min > arr[i]) 12 | min = arr[i]; 13 | } 14 | return min; 15 | } 16 | return min; 17 | } 18 | 19 | // 折半缩小范围 20 | int find_part(int *arr, int length) { 21 | int min = INT32_MAX; 22 | if((arr != nullptr) &&(length > 0)) { 23 | int p1 = 0; 24 | int p2 = length - 1; 25 | while(arr[p1] > arr[p2]) { 26 | if (p1 + 1 == p2) 27 | return arr[p2]; 28 | int mid = (p1 + p2) / 2; 29 | (arr[mid] >= arr[p1]) ? (p1 = mid) : (p2 = mid); 30 | } 31 | } 32 | return min; 33 | } 34 | 35 | int main() { 36 | int arr[5] = {3, 4, 5, 1, 2}; 37 | // int min = find_one_by_one(arr, 5); 38 | // int min = find_part(arr, 5); 39 | // cout << min; 40 | return 0; 41 | } -------------------------------------------------------------------------------- /code/28.包含min函数的栈.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | class new_stack { 8 | public: 9 | new_stack(void){}; 10 | T pop(); 11 | void push(const T& node); 12 | T min(); 13 | ~new_stack(void){}; 14 | private : 15 | stack data_stack; 16 | stack min_stack; 17 | }; 18 | template 19 | T new_stack::pop() { 20 | // 弹出元素前检查栈内是否有元素 21 | if((!data_stack.empty()) && (!min_stack.empty())) { 22 | data_stack.pop(); 23 | min_stack.pop(); 24 | } 25 | } 26 | template 27 | void new_stack::push(const T& node) { 28 | data_stack.push(node); 29 | // 特殊处理min_stack为空情况(注意顺序) 30 | if(min_stack.empty() || (node < min_stack.top())) 31 | min_stack.push(node); 32 | else 33 | min_stack.push(min_stack.top()); 34 | } 35 | template 36 | T new_stack::min() { 37 | if((!data_stack.empty()) && (!min_stack.empty())) { 38 | return min_stack.top(); 39 | } 40 | } 41 | 42 | int main() { 43 | new_stack *s = new new_stack; 44 | s->push(1); 45 | s->push(3); 46 | s->push(2); 47 | s->push(5); 48 | s->pop(); 49 | s->pop(); 50 | cout << s->min() << endl; 51 | } -------------------------------------------------------------------------------- /code/48.第一个只出现一次的字符.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | char first_uni(char *str, int length) { 7 | if((str == nullptr) || (length <=0)) 8 | throw exception(); 9 | int pos[26]; 10 | for(int i = 0; i < 26; ++i) 11 | pos[i] = -INT32_MAX; 12 | for(int i = 0; i < length; ++i){ 13 | if(pos[str[i] - 'a'] == -INT32_MAX) 14 | pos[str[i] - 'a'] = i; 15 | else if(pos[str[i] - 'a'] == INT32_MAX) 16 | continue; 17 | else 18 | pos[str[i] - 'a'] = INT32_MAX; 19 | } 20 | int offset = 0; 21 | int min = INT32_MAX; 22 | for(int i = 0; i < 26; ++i) { 23 | if((pos[i] != -INT32_MAX) && (pos[i] != INT32_MAX)) { 24 | if(pos[i] < min) { 25 | min = pos[i]; 26 | offset = i; 27 | } 28 | } 29 | } 30 | for (int i = 0; i < 26; i++) 31 | if((pos[i] != -INT32_MAX) && (pos[i] != INT32_MAX)) 32 | cout << "post[i] = " << pos[i] << " i = " << i << endl; 33 | if(min == INT32_MAX) 34 | return '\0'; 35 | return ('a' + offset); 36 | } 37 | 38 | int main() { 39 | char str[] = "kkggggggggggogrowxv"; 40 | cout << first_uni(str, strlen(str)); 41 | return 0; 42 | } -------------------------------------------------------------------------------- /code/22.反转链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct list_node { 6 | int data; 7 | list_node *next; 8 | }; 9 | 10 | list_node* reverse_list(list_node* phead) { 11 | list_node *p_reverse = nullptr; 12 | if(phead != nullptr) { 13 | list_node *p_pre = nullptr;; 14 | list_node *p_now = phead; 15 | list_node *p_next = p_now->next; 16 | while(p_now != nullptr) { 17 | p_next = p_now->next; 18 | if(p_next == nullptr) 19 | p_reverse = p_now; 20 | p_now->next = p_pre; 21 | p_pre = p_now; 22 | p_now = p_next; 23 | } 24 | } 25 | return p_reverse; 26 | } 27 | 28 | list_node* create_link_list() { 29 | list_node* pmove = new struct list_node; 30 | list_node* p = pmove; 31 | pmove->data = 1; 32 | pmove->next = nullptr; 33 | for(int i = 2; i <= 5; ++i) { 34 | list_node* p_new = new list_node; 35 | p_new->data = i; 36 | p_new->next = nullptr; 37 | pmove->next = p_new; 38 | pmove = p_new; 39 | } 40 | return p; 41 | } 42 | 43 | int main() { 44 | list_node* phead = create_link_list(); 45 | list_node* p = reverse_list(phead); 46 | while(p != nullptr) { 47 | cout << p->data; 48 | p = p->next; 49 | } 50 | return 0; 51 | } -------------------------------------------------------------------------------- /code/15.打印1到最大的n位数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | bool increment(char *number) { 7 | int length = strlen(number); 8 | bool is_overflow = false; 9 | int takeover = 0; 10 | for(int i = length - 1; i >= 0; --i) { 11 | int num = number[i] - '0' + takeover; 12 | if(i == length - 1) 13 | ++num; 14 | if(num <= 9) { 15 | number[i] = num + '0'; 16 | break; 17 | } 18 | else { 19 | if(i == 0) 20 | is_overflow = true; 21 | else { 22 | takeover = 1; 23 | num -= 10; 24 | number[i] = '0' + num; 25 | } 26 | } 27 | } 28 | return is_overflow; 29 | } 30 | 31 | void print_num(char *number) { 32 | int length = strlen(number); 33 | for(int i = 0; i < length; ++i) { 34 | if((number[i] == '0') && (i != length - 1)) 35 | continue; 36 | else 37 | printf("%c", number[i]); 38 | } 39 | printf("\n"); 40 | } 41 | 42 | int main() { 43 | int n; 44 | cin >> n; 45 | char *number = new char[n + 1]; 46 | memset(number, '0', n); 47 | number[n] = '\0'; 48 | while(!increment(number)) { 49 | print_num(number); 50 | } 51 | delete number[]; 52 | return 0; 53 | } -------------------------------------------------------------------------------- /code/7.用两个栈实现队列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 定义模板类,形式template 或者template 7 | template 8 | class new_queue { 9 | public: 10 | // 构造函数析构函数 11 | new_queue(void){}; 12 | ~new_queue(void){}; 13 | // 操作类型为通用类型 14 | void append_tail(const T &node); 15 | T delete_head(); 16 | private: 17 | stack stack1; 18 | stack stack2; 19 | }; 20 | // 使用T的地方都需要先加上template 21 | template 22 | void new_queue::append_tail(const T& node) { 23 | stack1.push(node); 24 | } 25 | template 26 | T new_queue::delete_head() { 27 | // 只要stack2为空则先把stack1内容退栈压入 28 | if(stack2.empty()) { 29 | while(!stack1.empty()) { 30 | stack2.push(stack1.top()); 31 | stack1.pop(); 32 | } 33 | } 34 | // 执行完上一步仍为空,表示队列为空 35 | if(stack2.empty()) 36 | throw new exception(); 37 | T node = stack2.top(); 38 | stack2.pop(); 39 | return node; 40 | } 41 | 42 | int main() { 43 | new_queue queue; 44 | queue.append_tail(1); 45 | queue.append_tail(2); 46 | cout << queue.delete_head() << endl; 47 | queue.append_tail(3); 48 | cout << queue.delete_head() << endl; 49 | cout << queue.delete_head() << endl; 50 | // cout << queue.delete_head() << endl; 51 | return 0; 52 | } -------------------------------------------------------------------------------- /code/25.二叉树镜像.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef struct tree Tree; 6 | struct tree { 7 | int data; 8 | Tree* right_tree; 9 | Tree* left_tree; 10 | }; 11 | 12 | Tree* create_tree_a() { 13 | Tree* p = new Tree; 14 | Tree* left = new Tree; 15 | left->right_tree = left->left_tree = nullptr; 16 | left->data = 9; 17 | Tree* right = new Tree; 18 | right->right_tree = right->left_tree = nullptr; 19 | right->data = 2; 20 | p->data = 8; 21 | p->left_tree = left; 22 | p->right_tree = right; 23 | } 24 | 25 | void exchange(Tree* proot) { 26 | Tree* ptemp = proot->left_tree; 27 | proot->left_tree = proot->right_tree; 28 | proot->right_tree = ptemp; 29 | } 30 | 31 | void mirror(Tree* proot) { 32 | if(proot == nullptr) 33 | return; 34 | if((proot->left_tree != nullptr) || (proot->right_tree != nullptr)) { 35 | exchange(proot); 36 | mirror(proot->left_tree); 37 | mirror(proot->right_tree); 38 | } 39 | return; 40 | } 41 | 42 | void print_tree(Tree* ptree) { 43 | if(ptree != nullptr) 44 | cout << ptree->data << endl; 45 | if(ptree->left_tree) 46 | print_tree(ptree->left_tree); 47 | if(ptree->right_tree) 48 | print_tree(ptree->right_tree); 49 | } 50 | 51 | int main() { 52 | Tree* tree_a = create_tree_a(); 53 | // print_tree(tree_a); 54 | mirror(tree_a); 55 | print_tree(tree_a); 56 | } -------------------------------------------------------------------------------- /code/29.栈的压入弹出序列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | bool is_pop_order(const int *push_order, const int *pop_order, int length) { 7 | bool is_order = false; 8 | if((push_order != nullptr) && (pop_order != nullptr) && (length > 0)) { 9 | int i_pop = 0; 10 | int i_push = 0; 11 | stack stack; 12 | // 未pop完数据 13 | while(i_pop != length) { 14 | // 栈空则按入栈顺序一直压栈直到栈顶压入第一个出栈序首元素 15 | while (((stack.empty()) || stack.top() != pop_order[i_pop])) 16 | stack.push(push_order[i_push++]); 17 | // 不存在出栈序,返回false,否则栈顶元素出栈 18 | if (stack.top() != pop_order[i_pop]) 19 | return false; 20 | else { 21 | stack.pop(); 22 | ++i_pop; 23 | } 24 | } 25 | if (stack.empty()) 26 | is_order = true; 27 | } 28 | return is_order; 29 | } 30 | int main() { 31 | int push_order[5] = {1, 2, 3, 4, 5}; 32 | int pop_order_1[5] = {4, 5, 3, 2, 1}; 33 | int pop_order_2[5] = {4, 3, 5, 1, 2}; 34 | int pop_order_3[5] = {5, 4, 3, 2, 1}; 35 | cout << is_pop_order(push_order, pop_order_1, (sizeof(pop_order_1) / sizeof(int))) << endl; 36 | cout << is_pop_order(push_order, pop_order_2, (sizeof(pop_order_2)) / sizeof(int))<< endl; 37 | cout << is_pop_order(push_order, pop_order_3, (sizeof(pop_order_3)) / sizeof(int))<< endl; 38 | } -------------------------------------------------------------------------------- /code/55.和为s的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 基于双指针 7 | bool exist_sum(int *array, int length, int num) { 8 | if((array == nullptr) && (length <= 0)) 9 | return false; 10 | int begin = 0; 11 | int end = length - 1; 12 | while(begin < end) { 13 | if(array[begin] + array[end] == num) 14 | return true; 15 | else if(array[begin] + array[end] < num) 16 | begin += 1; 17 | else 18 | end -= 1; 19 | } 20 | return false; 21 | } 22 | 23 | // 基于二分查找 24 | bool binary_search(int *array, int begin, int end, int num) { 25 | if((array == nullptr) || (begin > end)) 26 | return false; 27 | while(begin <= end) { 28 | int mid = (begin + end) / 2; 29 | if(num == array[mid]) 30 | return true; 31 | else if(num < array[mid]) 32 | end = mid - 1; 33 | else 34 | begin = mid + 1; 35 | } 36 | return false; 37 | } 38 | 39 | bool exist_search(int *array, int length, int num) { 40 | for(int i = 0; i < length; ++i) { 41 | if(binary_search(array, i + 1, length - 1, num - array[i])) 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | int main() { 48 | int num; 49 | cin >> num; 50 | int array[6] = {1, 2, 4, 7, 11, 15}; 51 | int length = sizeof(array) / sizeof(int); 52 | bool exist = exist_sum(array, length, num); 53 | cout << exist << endl; 54 | bool exist_search_sum = exist_search(array, length, num); 55 | cout << exist_search_sum << endl; 56 | return 0; 57 | } -------------------------------------------------------------------------------- /code/46.最长不含重复字符的子字符串.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // liner * set,O(nlogn) 8 | int max_uni(char *str, int length) { 9 | if((str == nullptr) || (length <= 0)) 10 | throw exception(); 11 | int cur_len = 0; 12 | int max_len = 0; 13 | multiset c_set; 14 | for(int i = 0; i < length; ++i) { 15 | if(!(c_set.count(str[i]))) { 16 | c_set.insert(str[i]); 17 | ++cur_len; 18 | } 19 | else { 20 | if(cur_len >= max_len) 21 | max_len = cur_len; 22 | c_set.clear(); 23 | cur_len = 1; 24 | } 25 | } 26 | if(cur_len >= max_len) 27 | max_len = cur_len; 28 | return max_len; 29 | } 30 | 31 | int max_dp(char* str, int length) { 32 | if((str == nullptr) || (length <= 0)) 33 | throw exception(); 34 | int cur_len = 0; 35 | int max_len = 0; 36 | int pos[26]; 37 | for(int i = 0; i < 26; ++i) 38 | pos[i] = -1; 39 | for(int i = 0; i < length; ++i) { 40 | int pre_index = pos[str[i] - 'a']; 41 | if((pre_index < 0) || (i - pre_index > cur_len)) 42 | ++cur_len; 43 | else { 44 | if(cur_len > max_len) 45 | max_len = cur_len; 46 | cur_len = i - pre_index; 47 | } 48 | pos[str[i] - 'a'] = i; 49 | } 50 | 51 | if(cur_len > max_len) 52 | max_len = cur_len; 53 | return max_len; 54 | } 55 | int main() { 56 | char str[10] = "qwertyuio"; 57 | cout << max_uni(str, strlen(str)) << endl; 58 | cout << max_dp(str, strlen(str)); 59 | return 0; 60 | } -------------------------------------------------------------------------------- /code/30.从上到下打印二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct tree { 7 | int data; 8 | struct tree* left; 9 | struct tree* right; 10 | }; 11 | 12 | struct tree* create_tree() { 13 | struct tree* proot = new struct tree; 14 | struct tree* pleft = new struct tree; 15 | struct tree* pright = new struct tree; 16 | proot->data = 10; 17 | proot->left = pleft; 18 | proot->right = pright; 19 | pleft->data = 8; 20 | pleft->left = nullptr; 21 | pleft->right = nullptr; 22 | pright->data = 6; 23 | pright->left = nullptr; 24 | pright->right = nullptr; 25 | return proot; 26 | } 27 | 28 | void print_tree_up_to_down(struct tree* proot) { 29 | if(proot != nullptr) { 30 | queue tree_queue; 31 | tree_queue.push(proot); 32 | while(!tree_queue.empty()) { 33 | cout << tree_queue.front()->data << endl; 34 | if(tree_queue.front()->left != nullptr) 35 | tree_queue.push(tree_queue.front()->left); 36 | // 这里不要使用else if 37 | if(tree_queue.front()->right != nullptr) 38 | tree_queue.push(tree_queue.front()->right); 39 | tree_queue.pop(); 40 | } 41 | } 42 | } 43 | 44 | void print_tree(struct tree* proot) { 45 | if(proot == nullptr) 46 | return; 47 | if(proot != nullptr) { 48 | cout << proot->data << endl; 49 | print_tree(proot->left); 50 | print_tree(proot->right); 51 | } 52 | } 53 | 54 | int main() { 55 | struct tree* proot = create_tree(); 56 | // print_tree(proot); 57 | print_tree_up_to_down(proot); 58 | return 0; 59 | } -------------------------------------------------------------------------------- /code/26.对称的二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef struct tree Tree; 6 | struct tree { 7 | int data; 8 | Tree* right_tree; 9 | Tree* left_tree; 10 | }; 11 | 12 | Tree* create_tree_a() { 13 | Tree* p = new Tree; 14 | Tree* left = new Tree; 15 | left->right_tree = left->left_tree = nullptr; 16 | left->data = 4; 17 | Tree* right = new Tree; 18 | right->right_tree = right->left_tree = nullptr; 19 | right->data = 4; 20 | p->data = 8; 21 | p->left_tree = left; 22 | p->right_tree = right; 23 | } 24 | 25 | void print_tree(Tree* ptree) { 26 | if(ptree != nullptr) 27 | cout << ptree->data << endl; 28 | if(ptree->left_tree) 29 | print_tree(ptree->left_tree); 30 | if(ptree->right_tree) 31 | print_tree(ptree->right_tree); 32 | } 33 | 34 | bool has_one_null(Tree* p) { 35 | if((p->left_tree == nullptr) && (p->right_tree != nullptr)) 36 | return true; 37 | if((p->right_tree == nullptr) && (p->left_tree != nullptr)) 38 | return true; 39 | return false; 40 | } 41 | 42 | bool is_symmetrical(Tree* proot) { 43 | if(proot == nullptr) 44 | return false; 45 | if(has_one_null(proot)) 46 | return false; 47 | if((proot->left_tree == nullptr) && (proot->left_tree == nullptr)) 48 | return true; 49 | if((proot->left_tree != nullptr) && (proot->right_tree != nullptr)) { 50 | if(proot->left_tree->data == proot->right_tree->data) { 51 | return is_symmetrical(proot->left_tree) && is_symmetrical(proot->right_tree); 52 | } 53 | } 54 | return false; 55 | } 56 | 57 | int main() { 58 | Tree* tree_a = create_tree_a(); 59 | // print_tree(tree_a); 60 | cout << is_symmetrical(tree_a); 61 | } -------------------------------------------------------------------------------- /code/1.数组中重复的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // 找出全部,改变数组,时间O(nlogn),空间O(1) 8 | void sort_version(int *arr) { 9 | sort(arr, arr + 7); 10 | for(int i = 0; i < 7; ++i) { 11 | int j; 12 | for(j = 1; arr[i] == arr[i + j]; ++j); 13 | if(j != 1){ 14 | cout << arr[i] << endl; 15 | i = i + j - 1; 16 | } 17 | } 18 | } 19 | 20 | // 找出全部,不改变数组,时间O(n),空间O(n) 21 | void hash_version(int *arr, int length) { 22 | map map; 23 | // for(auto : arr) 24 | for(int i = 0; i < length; ++i) { 25 | ++map[arr[i]]; 26 | } 27 | for(auto var : map) { 28 | if (var.second != 1) 29 | cout << var.first << endl; 30 | } 31 | } 32 | 33 | // 只找一个,可以改变数组,时间O(n),空间O(1) 34 | bool solution(int *arr, int length, int *dest) { 35 | // int length = sizeof(arr); 36 | // 输入是否有效 37 | if(arr == nullptr || length <= 0) 38 | return false; 39 | // 变量是否符合本方法 40 | for(int i = 0; i < length; ++i) 41 | if(arr[i] < 0 || arr[i] > length - 1) 42 | return false; 43 | for(int i = 0; i < length; ++i) { 44 | while(i != arr[i]) { 45 | if(arr[i] == arr[arr[i]]) { 46 | *dest = arr[i]; 47 | return true; 48 | } 49 | int temp = arr[i]; 50 | arr[i] = arr[temp]; 51 | arr[temp] = temp; 52 | } 53 | } 54 | return false; 55 | } 56 | 57 | int main() { 58 | int arr[7] = {2 ,3, 1, 0, 2, 5, 3}; 59 | int *dest = new int; 60 | // int length = sizeof(arr); 61 | int length = sizeof(arr) / sizeof(int); 62 | // sort_version(arr); 63 | // hash_version(arr, length); 64 | solution(arr, length, dest); 65 | cout << *dest << endl; 66 | return 0; 67 | } -------------------------------------------------------------------------------- /code/37.出现次数超过一半的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void count_by_sort(int *array, int n) { 8 | if((array != nullptr) && (n >= 1)) 9 | sort(array, array + n); 10 | for(int i = 1; i < n; ++i) { 11 | int count = 1; 12 | if(array[i] == array[i + 1]) { 13 | while(array[i] == array[i + 1]) { 14 | ++count; 15 | ++i; 16 | } 17 | } 18 | if(count >= (n / 2)) { 19 | cout << array[i] << endl; 20 | return; 21 | } 22 | } 23 | } 24 | 25 | void count_by_hash(int *array, int n) { 26 | if((array != nullptr) && (n >= 1)) { 27 | map map; 28 | for (int i = 0; i < n; ++i) 29 | ++map[array[i]]; 30 | int num = -INT32_MAX; 31 | int max = -INT32_MAX; 32 | for (auto var : map) { 33 | if (max < var.second) { 34 | num = var.first; 35 | max = var.second; 36 | } 37 | } 38 | if (max >= (n / 2)) 39 | cout << num << endl; 40 | } 41 | } 42 | 43 | void count_by_cal(int *array, int n) { 44 | if((array != nullptr) && (n >= 1)) { 45 | map stat; 46 | int result = array[0]; 47 | int times = 1; 48 | for(int i = 1; i < n; ++i) { 49 | if(times == 0) { 50 | result = array[i]; 51 | times = 1; 52 | } 53 | if(array[i] == result) 54 | ++times; 55 | else 56 | --times; 57 | } 58 | if(times > 0) 59 | cout << result << endl; 60 | } 61 | } 62 | 63 | int main() { 64 | int array[9] = {1, 2, 3, 2, 2, 2, 5, 4, 2}; 65 | count_by_sort(array, 9); 66 | count_by_hash(array, 9); 67 | count_by_cal(array, 9); 68 | return 0; 69 | } -------------------------------------------------------------------------------- /code/2.二维数组中的查找.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 与右上角元素比较 7 | bool right_corner_find(int target, vector> vec) { 8 | if(!vec.empty()) { 9 | // 二维向量获取行列大小 10 | int rows = vec.size(); 11 | int cols = vec[0].size(); 12 | if((rows > 0) && (cols > 0)) { 13 | // 右上角元素坐标 14 | int corner_row = 0; 15 | int corner_col = cols - 1; 16 | while((corner_row < rows) && (corner_col >= 0)) { 17 | if(target < vec[corner_row][corner_col]) 18 | corner_col = corner_col - 1; 19 | else if(target > vec[corner_row][corner_col]) 20 | corner_row = corner_row + 1; 21 | else 22 | return true; 23 | } 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | // 与左上角元素比较 30 | bool left_corner_find(int target, vector> vec) { 31 | if(!vec.empty()) { 32 | int rows = vec.size(); 33 | int cols = vec[0].size(); 34 | if((rows > 0) && (cols > 0)) { 35 | int corner_row = rows - 1; 36 | int corner_col = 0; 37 | while((corner_row >= 0) && (corner_col < cols)) { 38 | if(target > vec[corner_row][corner_col]) 39 | corner_col = corner_col + 1; 40 | else if(target < vec[corner_row][corner_col]) 41 | corner_row = corner_row - 1; 42 | else 43 | return true; 44 | } 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | int main() { 51 | int target; 52 | cin >> target; 53 | vector> vec = {{1, 2, 8, 9}, {2, 4, 9, 12}, 54 | {4, 7, 10, 13}, {6, 8, 11, 15}}; 55 | // cout << right_corner_find(target, vec) << endl; 56 | // cout << left_corner_find(target, vec) << endl; 57 | return 0; 58 | } -------------------------------------------------------------------------------- /code/3.替换空格.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 与右上角元素比较 7 | bool right_corner_find(int target, vector> vec) { 8 | if(!vec.empty()) { 9 | // 二维向量获取行列大小 10 | int rows = vec.size(); 11 | int cols = vec[0].size(); 12 | if((rows > 0) && (cols > 0)) { 13 | // 右上角元素坐标 14 | int corner_row = 0; 15 | int corner_col = cols - 1; 16 | while((corner_row < rows) && (corner_col >= 0)) { 17 | if(target < vec[corner_row][corner_col]) 18 | corner_col = corner_col - 1; 19 | else if(target > vec[corner_row][corner_col]) 20 | corner_row = corner_row + 1; 21 | else 22 | return true; 23 | } 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | // 与左上角元素比较 30 | bool left_corner_find(int target, vector> vec) { 31 | if(!vec.empty()) { 32 | int rows = vec.size(); 33 | int cols = vec[0].size(); 34 | if((rows > 0) && (cols > 0)) { 35 | int corner_row = rows - 1; 36 | int corner_col = 0; 37 | while((corner_row >= 0) && (corner_col < cols)) { 38 | if(target > vec[corner_row][corner_col]) 39 | corner_col = corner_col + 1; 40 | else if(target < vec[corner_row][corner_col]) 41 | corner_row = corner_row - 1; 42 | else 43 | return true; 44 | } 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | int main() { 51 | int target; 52 | cin >> target; 53 | vector> vec = {{1, 2, 8, 9}, {2, 4, 9, 12}, 54 | {4, 7, 10, 13}, {6, 8, 11, 15}}; 55 | // cout << right_corner_find(target, vec) << endl; 56 | // cout << left_corner_find(target, vec) << endl; 57 | return 0; 58 | } -------------------------------------------------------------------------------- /code/39.数据流中的中位数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | bool error_null_array = false; 7 | 8 | template class dynamic_array { 9 | public: 10 | dynamic_array(){}; 11 | ~dynamic_array(){}; 12 | void insert(T node); 13 | T get_mid(); 14 | private: 15 | vector min_heap; 16 | vector max_heap; 17 | }; 18 | template void dynamic_array::insert(T node) { 19 | int length = min_heap.size() + max_heap.size(); 20 | if((length & 1) == 0) { 21 | if((max_heap.size() > 0) && (node < max_heap[0])) { 22 | max_heap.push_back(node); 23 | push_heap(max_heap.begin(), max_heap.end(), less()); 24 | node = max_heap[0]; 25 | pop_heap(max_heap.begin(), max_heap.end(), less()); 26 | max_heap.pop_back(); 27 | } 28 | min_heap.push_back(node); 29 | push_heap(min_heap.begin(), min_heap.end(), greater()); 30 | } 31 | else { 32 | if((min_heap.size() > 0) && (node > min_heap[0])) { 33 | min_heap.push_back(node); 34 | push_heap(min_heap.begin(), min_heap.end(), greater()); 35 | node = min_heap[0]; 36 | pop_heap(min_heap.begin(), min_heap.end(), greater()); 37 | min_heap.pop_back(); 38 | } 39 | max_heap.push_back(node); 40 | push_heap(max_heap.begin(), max_heap.end(), less()); 41 | } 42 | } 43 | template T dynamic_array::get_mid() { 44 | int length = min_heap.size() + max_heap.size(); 45 | if(length == 0){ 46 | error_null_array = true; 47 | return -INT32_MAX; 48 | } 49 | return ((length & 1) == 1) ? min_heap[0] : ((min_heap[0] + max_heap[0]) / 2); 50 | } 51 | 52 | int main() { 53 | dynamic_array array; 54 | array.insert(2); 55 | array.insert(3); 56 | array.insert(4); 57 | array.insert(5); 58 | array.insert(6); 59 | cout << array.get_mid() << endl; 60 | return 0; 61 | } -------------------------------------------------------------------------------- /code/45.礼物的最大价值.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // greedy, wrong 6 | int max_greedy(int (*array)[4]) { 7 | if(array == nullptr) 8 | throw exception(); 9 | int max = array[0][0]; 10 | int pos_i = 0; 11 | int pos_j = 0; 12 | while((pos_i != 3) || (pos_j != 3)) { 13 | if(pos_i == 3) { 14 | while(pos_j != 3) { 15 | max += array[pos_i][pos_j + 1]; 16 | pos_j += 1; 17 | } 18 | } 19 | if(pos_j == 3) { 20 | while(pos_i != 3) { 21 | max += array[pos_i + 1][pos_j]; 22 | pos_j += 1; 23 | } 24 | } 25 | if((pos_i + 1 <= 3) && (array[pos_i + 1][pos_j] >= array[pos_i][pos_j + 1])) { 26 | max += array[pos_i + 1][pos_j]; 27 | pos_i += 1; 28 | } 29 | if((pos_j + 1 <= 3) && (array[pos_i + 1][pos_j] < array[pos_i][pos_j + 1])){ 30 | max += array[pos_i][pos_j + 1]; 31 | pos_j += 1; 32 | } 33 | } 34 | return max; 35 | } 36 | 37 | void ini_arr(int (*count)[4], int (*array)[4]) { 38 | count[0][0] = array[0][0]; 39 | for(int i = 1; i < 4; ++i) 40 | count[i][0] = array[i][0] + count[i - 1][0]; 41 | for(int j = 1; j < 4; ++j) 42 | count[0][j] = array[0][j] + count[0][j - 1]; 43 | } 44 | 45 | int max_dp(int (*array)[4]) { 46 | if (array == nullptr) 47 | throw exception(); 48 | int count[4][4]; 49 | ini_arr(count, array); 50 | for (int i = 1; i < 4; ++i) { 51 | for (int j = 1; j < 4; ++j) { 52 | if(count[i - 1][j] > count[i][j - 1]) 53 | count[i][j] = count[i - 1][j] + array[i][j]; 54 | else 55 | count[i][j] = count[i][j - 1] + array[i][j]; 56 | } 57 | } 58 | return count[3][3]; 59 | } 60 | 61 | int main() { 62 | int array[4][4] = { 63 | {1, 10, 3, 8}, 64 | {12, 2, 9, 6}, 65 | {5, 7, 4, 11}, 66 | {3, 7, 16, 5} 67 | }; 68 | cout << max_greedy(array) << endl; 69 | cout << max_dp(array); 70 | return 0; 71 | } -------------------------------------------------------------------------------- /code/24.树的子结构.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef struct tree Tree; 6 | struct tree { 7 | int data; 8 | Tree* right_tree; 9 | Tree* left_tree; 10 | }; 11 | 12 | Tree* create_tree_a() { 13 | Tree* p = new Tree; 14 | Tree* left = new Tree; 15 | left->right_tree = left->left_tree = nullptr; 16 | left->data = 9; 17 | Tree* right = new Tree; 18 | right->right_tree = right->left_tree = nullptr; 19 | right->data = 2; 20 | p->data = 8; 21 | p->left_tree = left; 22 | p->right_tree = right; 23 | } 24 | 25 | Tree* create_tree_b(Tree* tree_a) { 26 | Tree* p = new Tree; 27 | p->data = 8; 28 | p->right_tree = nullptr; 29 | p->left_tree = tree_a; 30 | } 31 | 32 | bool tree_b_has_tree_a(Tree* tree_b, Tree* tree_a) { 33 | if(tree_a == nullptr) 34 | return true; 35 | if(tree_b == nullptr) 36 | return false; 37 | if(tree_a->data != tree_b->data) 38 | return false; 39 | return (tree_b_has_tree_a(tree_b->left_tree, tree_a->left_tree) && tree_b_has_tree_a(tree_b->right_tree, tree_a->right_tree)); 40 | } 41 | 42 | bool has_subtree(Tree* tree_b, Tree* tree_a) { 43 | bool result = false; 44 | if((tree_a != nullptr) && (tree_b != nullptr)) { 45 | // 定根 46 | if (tree_a->data == tree_b->data) 47 | result = tree_b_has_tree_a(tree_b, tree_a); 48 | // 递归左子树 49 | if (!result) 50 | result = has_subtree(tree_b->left_tree, tree_a); 51 | // 递归右子树 52 | if (!result) 53 | result = has_subtree(tree_b->right_tree, tree_a); 54 | } 55 | return result; 56 | } 57 | 58 | void print_tree(Tree* ptree) { 59 | if(ptree != nullptr) 60 | cout << ptree->data << endl; 61 | if(ptree->left_tree) 62 | print_tree(ptree->left_tree); 63 | if(ptree->right_tree) 64 | print_tree(ptree->right_tree); 65 | } 66 | 67 | int main() { 68 | Tree* tree_a = create_tree_a(); 69 | Tree* tree_b = create_tree_b(tree_a); 70 | // print_tree(tree_a); 71 | // print_tree(tree_b); 72 | bool has_sub = has_subtree(tree_b, tree_a); 73 | cout << has_sub << endl; 74 | } -------------------------------------------------------------------------------- /code/38.最小的k个数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void swap(int* array, int i, int j) { 8 | int temp = array[i]; 9 | array[i] = array[j]; 10 | array[j] = temp; 11 | } 12 | 13 | int part(int *array, int start, int end) { 14 | int low = start; 15 | int high = end; 16 | int pivot = array[low]; 17 | while(low < high) { 18 | if(pivot > array[high]) { 19 | swap(array, low, high); 20 | ++low; 21 | } 22 | else if(pivot <= array[low]) { 23 | swap(array, low, high); 24 | --high; 25 | } 26 | } 27 | return low; 28 | } 29 | 30 | // O(n),但会修改原序列 31 | void kth_by_part(int *array, int n, int k) { 32 | if((array == nullptr) || (k <= 0) || (n <= 0) || (n < k)) 33 | return; 34 | int start = 0; 35 | int end = n - 1; 36 | int index = part(array, start, end); 37 | while(index != (k - 1)) { 38 | if(index > (k - 1)) { 39 | end = index - 1; 40 | index = part(array, start, end); 41 | } 42 | if(index < (k - 1)) { 43 | start = index + 1; 44 | index = part(array, start, end); 45 | } 46 | } 47 | for(int i = 0; i < k; ++i) 48 | cout << array[i] << endl; 49 | } 50 | 51 | // O(nlogk),不修改原序列,适合大数据 52 | void get_least_number(const vector& data, multiset> ini_set, int k) { 53 | if((k < 1) || data.size() < k) 54 | return; 55 | for(auto it = data.begin(); it != data.end(); ++it) { 56 | // 集合够存直接存 57 | if(ini_set.size() < k) 58 | ini_set.insert(*it); 59 | else { 60 | // 不够存时,若新数小于当前集合最大数,删去最大数并加入新元素 61 | // multiset>最大数位于ini_set.begin() 62 | auto it_greatest = ini_set.begin(); 63 | if(*it < *(ini_set.begin())) { 64 | ini_set.erase(it_greatest); 65 | ini_set.insert(*it); 66 | } 67 | } 68 | } 69 | for(auto it = ini_set.begin(); it != ini_set.end(); ++it) 70 | cout << *it << endl; 71 | } 72 | int main() { 73 | int array[9] = {5, 8, 7, 9, 1, 4, 2, 7, 11}; 74 | kth_by_part(array, 9, 3); 75 | multiset> ini_set; 76 | vector vec = {5, 8, 7, 9, 1, 4, 2, 7, 11}; 77 | get_least_number(vec, ini_set, 3); 78 | return 0; 79 | } -------------------------------------------------------------------------------- /code/21.链表中环的入口节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct link_list { 6 | int data; 7 | struct link_list *next; 8 | }; 9 | 10 | // 创建链表 11 | link_list* create_circle_link_list() { 12 | link_list* p = new struct link_list; 13 | link_list* pmove = p; 14 | link_list* pcircle = nullptr; 15 | p->next = nullptr; 16 | p->data = 1; 17 | for(int i = 2; i <= 10; ++i) { 18 | link_list* pnew = new link_list; 19 | pnew->data = i; 20 | pnew->next = nullptr; 21 | pmove->next = pnew; 22 | pmove = pnew; 23 | if(i == 7) 24 | pcircle = pmove; 25 | } 26 | pmove->next = pcircle; 27 | return p; 28 | } 29 | 30 | // 返回是否有环(快慢指针碰撞) 31 | link_list* check_link_list_has_circle(link_list* phead) { 32 | if(phead != nullptr) { 33 | link_list* pfast = phead; 34 | link_list* pslow = phead; 35 | while(pfast != nullptr) { 36 | pslow = pslow->next; 37 | pfast = pfast->next; 38 | if(pfast == nullptr) 39 | return false; 40 | pfast = pfast->next; 41 | if(pfast == pslow) { 42 | return pslow; 43 | } 44 | } 45 | } 46 | return nullptr; 47 | } 48 | 49 | // 计算环的大小(再次路过碰撞点) 50 | unsigned int calculate_link_list_length(link_list *pbumb) { 51 | unsigned int k = 1; 52 | link_list* pfast = pbumb->next->next; 53 | link_list* pslow = pbumb->next; 54 | while(pslow != pbumb) { 55 | ++k; 56 | pfast = pfast->next->next; 57 | pslow = pslow->next; 58 | } 59 | return k; 60 | } 61 | 62 | // 找到换入口(快指针先走环长) 63 | link_list *find_point(link_list *phead, unsigned int k) { 64 | link_list* pfast = phead; 65 | link_list* pslow = phead; 66 | while(k--) 67 | pfast = pfast->next; 68 | while(pfast != pslow) { 69 | pfast = pfast->next; 70 | pslow = pslow->next; 71 | } 72 | return pfast; 73 | } 74 | 75 | void print_link_list(link_list* phead) { 76 | while(phead != nullptr) { 77 | cout << phead->data << endl; 78 | phead = phead->next; 79 | } 80 | } 81 | 82 | int main() { 83 | link_list* phead = create_circle_link_list(); 84 | link_list* pbumb = check_link_list_has_circle(phead); 85 | unsigned int k = 0; 86 | if(pbumb) 87 | k = calculate_link_list_length(pbumb); 88 | link_list* ppoint = find_point(phead, k); 89 | cout << ppoint->data << endl; 90 | } -------------------------------------------------------------------------------- /code/23.合并两个排序的链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct link_list { 6 | int data; 7 | link_list *next; 8 | }; 9 | 10 | link_list *create_link_list(int n) { 11 | link_list* phead = new link_list; 12 | link_list* pmove = phead; 13 | if(phead != nullptr) { 14 | phead->data = n; 15 | phead->next = nullptr; 16 | } 17 | for(int i = n + 1; i < n + 5; ++i) { 18 | link_list *pnew = new link_list; 19 | if(pnew != nullptr) { 20 | pnew->data = i; 21 | pnew->next = nullptr; 22 | pmove->next = pnew; 23 | pmove = pnew; 24 | } 25 | } 26 | return phead; 27 | } 28 | 29 | // 迭代处理 30 | link_list* merge_link_list(link_list *phead_1, link_list* phead_2) { 31 | link_list *pmove = nullptr; 32 | link_list *p = nullptr; 33 | if((phead_1 != nullptr) && (phead_2 != nullptr)) { 34 | if(phead_1->data < phead_2->data) { 35 | pmove = phead_1; 36 | p = pmove; 37 | phead_1 = phead_1->next; 38 | } 39 | else { 40 | pmove = phead_2; 41 | p = pmove; 42 | phead_2 = phead_2->next; 43 | } 44 | 45 | while((phead_1 != nullptr) && (phead_2 != nullptr)) { 46 | if(phead_1->data < phead_2->data) { 47 | pmove->next = phead_1; 48 | pmove = phead_1; 49 | phead_1 = phead_1->next; 50 | } 51 | else { 52 | pmove->next = phead_2; 53 | pmove = phead_2; 54 | phead_2 = phead_2->next; 55 | } 56 | } 57 | if(phead_1 != nullptr) 58 | pmove->next = phead_1; 59 | else 60 | pmove->next = phead_2; 61 | } 62 | return p; 63 | } 64 | 65 | // 递归处理 66 | link_list *merge(link_list *phead1, link_list *phead2) { 67 | if(phead1 == nullptr) 68 | return phead2; 69 | else if(phead2 == nullptr) 70 | return phead1; 71 | link_list *p = nullptr; 72 | if(phead1->data < phead2->data) { 73 | p = phead1; 74 | p->next = merge(phead1->next, phead2); 75 | } 76 | else { 77 | p = phead2; 78 | p->next = merge(phead1, phead2->next); 79 | } 80 | return p; 81 | } 82 | 83 | int main() { 84 | int i, j; 85 | cin >> i >> j; 86 | link_list *phead_1 = create_link_list(i); 87 | link_list *phead_2 = create_link_list(j); 88 | // link_list* p = merge(phead_1, phead_2); 89 | // link_list *phead = merge_link_list(phead_1, phead_2); 90 | return 0; 91 | } -------------------------------------------------------------------------------- /code/51.在排序数组中查找数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // 递归二分查找 6 | int binary_search_recursion(int *array, int length, int k, int begin, int end) { 7 | if((array == nullptr) || (length <= 0) || (begin > end)) 8 | return -1; 9 | int mid = (begin + end) / 2; 10 | int mid_data = array[mid]; 11 | if(mid_data == k) 12 | return mid; 13 | else if(mid_data > k) 14 | return binary_search_recursion(array, length, k, begin, mid - 1); 15 | else 16 | return binary_search_recursion(array, length, k, begin + 1, end); 17 | } 18 | 19 | // 迭代二分查找 20 | int binary_search_iteration(int *array, int length, int k, int begin, int end) { 21 | if((array == nullptr) || (length <= 0) || (begin > end)) 22 | return -1; 23 | // 注意可以取等 24 | while(begin <= end) { 25 | int mid = begin + ((end - begin) >> 2); 26 | if(array[mid] == k) 27 | return mid; 28 | else if(array[mid] > k) 29 | end = end - 1; 30 | else 31 | begin = begin + 1; 32 | } 33 | return -1; 34 | } 35 | 36 | int get_first_k(int *array, int length, int k, int begin, int end) { 37 | if((array == nullptr) || (length <= 0) || (begin > end)) 38 | return -1; 39 | int mid = (begin + end) / 2; 40 | int mid_data = array[mid]; 41 | if(mid_data == k) { 42 | if(mid == 0) 43 | return mid; 44 | if((mid > 0) && (array[mid - 1] != k)) 45 | return mid; 46 | else 47 | return get_first_k(array, length, k, begin, mid - 1); 48 | } 49 | else if(mid_data > k) 50 | return get_first_k(array, length, k, begin, end - 1); 51 | else 52 | return get_first_k(array, length, k, begin + 1, end); 53 | } 54 | 55 | int get_last_k(int *array, int length, int k, int begin, int end) { 56 | if((array == nullptr) || (length <= 0) || (begin > end)) 57 | return -1; 58 | int mid = (begin + end) / 2; 59 | int mid_data = array[mid]; 60 | if(mid_data == k) { 61 | if(mid == length - 1) 62 | return mid; 63 | if((array[mid + 1] != k) && (mid < length - 1)) 64 | return mid; 65 | else 66 | return get_last_k(array, length, k, mid + 1, end); 67 | 68 | } 69 | else if(mid_data > k) 70 | return get_last_k(array, length, k, begin, end - 1); 71 | else 72 | return get_last_k(array, length, k, begin + 1, end); 73 | } 74 | 75 | int main() { 76 | int array[8] = {1, 2, 3, 3, 3, 3, 4, 5}; 77 | int length = sizeof(array) / sizeof(int); 78 | int k = 3; 79 | int first_k = get_first_k(array, length, k, 0, length - 1); 80 | int last_k = get_last_k(array, length, k, 0, length - 1); 81 | // check valid 82 | if((first_k > -1) && (last_k > -1) 83 | cout << last_k - first_k + 1<< endl; 84 | return 0; 85 | } -------------------------------------------------------------------------------- /code/50.两个链表的第一个公共节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef struct link_list { 7 | int data; 8 | struct link_list *next; 9 | }list; 10 | 11 | list* create_list() { 12 | list* phead = new list; 13 | phead->data = 1; 14 | phead->next = nullptr; 15 | for(int i = 2; i <= 5; ++i) { 16 | list* pnew = new list; 17 | pnew->data = i; 18 | pnew->next = phead; 19 | phead = pnew; 20 | } 21 | return phead; 22 | } 23 | 24 | void print_list(list *phead) { 25 | if(phead == nullptr) 26 | return; 27 | while(phead) { 28 | cout << phead->data << ' '; 29 | phead = phead->next; 30 | } 31 | cout << endl; 32 | } 33 | 34 | list* stack_fun(list* phead_1, list* phead_2) { 35 | if((phead_1 == nullptr) || (phead_2 == nullptr)) 36 | return nullptr; 37 | stack stack_1, stack_2; 38 | while(phead_1) { 39 | stack_1.push(phead_1); 40 | phead_1 = phead_1->next; 41 | } 42 | while(phead_2) { 43 | stack_2.push(phead_2); 44 | phead_2= phead_2->next; 45 | } 46 | list* first_common = nullptr; 47 | while(stack_1.top() == stack_2.top()) { 48 | first_common = stack_1.top(); 49 | stack_1.pop(); 50 | stack_2.pop(); 51 | } 52 | return first_common; 53 | } 54 | 55 | list* run_point_fun(list* phead_1, list* phead_2) { 56 | if((phead_1 == nullptr) || (phead_2 == nullptr)) 57 | return nullptr; 58 | list* pmove_1 = phead_1; 59 | list* pmove_2 = phead_2; 60 | int len_1 = 0; 61 | int len_2 = 0; 62 | while(pmove_1) { 63 | ++len_1; 64 | pmove_1 = pmove_1->next; 65 | } 66 | while(pmove_2) { 67 | ++len_2; 68 | pmove_2 = pmove_2->next; 69 | } 70 | int k = abs(len_1 - len_2); 71 | if(len_1 > len_2) { 72 | while(k--) { 73 | phead_1 = phead_1->next; 74 | } 75 | } 76 | else if(len_2 > len_1) { 77 | while(k--) { 78 | phead_2 = phead_2->next; 79 | } 80 | } 81 | list* first_common = nullptr; 82 | while((phead_1 != nullptr) && (phead_2 != nullptr)) { 83 | if(phead_1 != phead_2) { 84 | phead_1 = phead_1->next; 85 | phead_2 = phead_2->next; 86 | } 87 | if (phead_1 == phead_2) { 88 | first_common = phead_1; 89 | break; 90 | } 91 | } 92 | return first_common; 93 | } 94 | 95 | int main() { 96 | list* phead_1 = create_list(); 97 | list* phead_2 = phead_1; 98 | for(int i = 6; i <= 10; ++i) { 99 | list* pnew = new list; 100 | pnew->data = i; 101 | pnew->next = phead_2; 102 | phead_2 = pnew; 103 | } 104 | print_list(phead_1); 105 | print_list(phead_2); 106 | list* p_common_1 = stack_fun(phead_1, phead_2); 107 | cout << p_common_1->data << endl; 108 | list* p_common_2 = run_point_fun(phead_1, phead_2); 109 | cout << p_common_2->data << endl; 110 | return 0; 111 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Paper-Code 2 | 3 | > 纸上代码非纸上谈兵。 4 | 5 | --- 6 | 7 | # 索引 8 | 9 | | 序号 | 题目 | 代码 | 解答 | 10 | |:----:|:----:|:----:|:----:| 11 | |1|数组中重复的数字|[※](https://github.com/linw7/Paper-Code/tree/master/code/1.数组中重复的数字.cpp)|※| 12 | |2|二维数组中的查找|[※](https://github.com/linw7/Paper-Code/tree/master/code/2.二维数组中的查找.cpp)|※| 13 | |3|替换空格|[※](https://github.com/linw7/Paper-Code/tree/master/code/3.替换空格.cpp)|※| 14 | |4|从尾到头打印链表|[※](https://github.com/linw7/Paper-Code/tree/master/code/4.从尾到头打印链表.cpp)|※| 15 | |5|重建二叉树|※|※| 16 | |6|二叉树的下一个节点|※|※| 17 | |7|用两个栈实现队列|[※](https://github.com/linw7/Paper-Code/tree/master/code/7.用两个栈实现队列.cpp)|※| 18 | |8|斐波那契数列|[※](https://github.com/linw7/Paper-Code/tree/master/code/8.斐波那契数列.cpp)|※| 19 | |9|旋转数组的最小数字|[※](https://github.com/linw7/Paper-Code/tree/master/code/9.旋转数组的最小数字.cpp)|※| 20 | |10|矩阵中的路径|※|※| 21 | |11|机器人的运动范围|※|※| 22 | |12|剪绳子|※|※| 23 | |13|二进制中1的位数|[※](https://github.com/linw7/Paper-Code/tree/master/code/13.二进制中1的个数.cpp)|※| 24 | |14|数值的整数次方|[※](https://github.com/linw7/Paper-Code/tree/master/code/14.数值的整数次方.cpp)|※| 25 | |15|打印从1到最大的n位数|[※](https://github.com/linw7/Paper-Code/tree/master/code/15.打印1到最大的n位数.cpp)|※| 26 | |16|删除链表的节点|※|※| 27 | |17|正则表达式匹配|※|※| 28 | |18|表示数值的字符串|※|※| 29 | |19|调整数组使奇数位于偶数前面|[※](https://github.com/linw7/Paper-Code/tree/master/code/19.调整数组顺序使奇数位于偶数前面.cpp)|※| 30 | |20|链表中倒数第k个节点|[※](https://github.com/linw7/Paper-Code/tree/master/code/20.链表中倒数第k个结点.cpp)|※| 31 | |21|链表中环的入口节点|[※](https://github.com/linw7/Paper-Code/tree/master/code/21.链表中环的入口节点.cpp)|※| 32 | |22|反转链表|[※](https://github.com/linw7/Paper-Code/tree/master/code/22.反转链表.cpp)|※| 33 | |23|合并两个排序的链表|[※](https://github.com/linw7/Paper-Code/tree/master/code/23.合并两个排序的链表.cpp)|※| 34 | |24|树的子结构|[※](https://github.com/linw7/Paper-Code/tree/master/code/24.树的子结构.cpp)|※| 35 | |25|二叉树的镜像|[※](https://github.com/linw7/Paper-Code/tree/master/code/25.二叉树镜像.cpp)|※| 36 | |26|对称的二叉树|[※](https://github.com/linw7/Paper-Code/tree/master/code/26.对称的二叉树.cpp)|※| 37 | |27|顺时针打印矩阵|※|※| 38 | |28|包含min函数的栈|[※](https://github.com/linw7/Paper-Code/tree/master/code/28.包含min函数的栈.cpp)|※| 39 | |29|栈的压入、弹出序列|[※](https://github.com/linw7/Paper-Code/tree/master/code/29.栈的压入弹出序列.cpp)|※| 40 | |30|从上到下打印二叉树|[※](https://github.com/linw7/Paper-Code/tree/master/code/30.从上到下打印二叉树.cpp)|※| 41 | |31|二叉搜索树的后序遍历序列|※|※| 42 | |32|二叉树中和为某一值得路径|※|※| 43 | |33|复杂链表的复制|※|※| 44 | |34|二叉搜索树与双向链表|※|※| 45 | |35|序列化二叉树|※|※| 46 | |36|字符串的排列|※|※| 47 | |37|数组中出现次数超过一半的数字|[※](https://github.com/linw7/Paper-Code/tree/master/code/37.出现次数超过一半的数字.cpp)|※| 48 | |38|最小的k个数|[※](https://github.com/linw7/Paper-Code/tree/master/code/38.最小的k个数.cpp)|※| 49 | |39|数据流中的中位数|[※](https://github.com/linw7/Paper-Code/tree/master/code/39.流数据中的中位数.cpp)|※| 50 | |40|连续子数组的最大和|[※](https://github.com/linw7/Paper-Code/tree/master/code/40.连续子数组的最大和.cpp)|※| 51 | |41|1 - n整数中1出现的次数|[※](https://github.com/linw7/Paper-Code/tree/master/code/41.整数中1出现的次数.cpp)|※| 52 | |42|数字序列中的某一位的数字|※|※| 53 | |43|把数组排成最小的数|※|※| 54 | |44|把数字翻译成字符串|[※](https://github.com/linw7/Paper-Code/tree/master/code/44.把数字翻译成字符串.cpp)|※| 55 | |45|礼物的最大价值|[※](https://github.com/linw7/Paper-Code/tree/master/code/45.礼物的最大价值.cpp)|※| 56 | |46|最长不含重复字符的字符串|[※](https://github.com/linw7/Paper-Code/tree/master/code/46.最长不含重复字符的子字符串.cpp)|※| 57 | |47|丑数|※|※| 58 | |48|第一个只出现一次的字符|[※](https://github.com/linw7/Paper-Code/tree/master/code/48.第一个只出现一次的字符.cpp)|※| 59 | |49|数组中的逆序对|[※](https://github.com/linw7/Paper-Code/tree/master/code/)|※| 60 | |50|两个链表第一个公共节点|[※](https://github.com/linw7/Paper-Code/tree/master/code/50.两个链表的第一个公共节点.cpp)|※| 61 | |51|在排序数组中查找数字|[※](https://github.com/linw7/Paper-Code/tree/master/code/51.在排序数组中查找数字.cpp)|※| 62 | |52|二叉搜索树的第k大节点|[※](https://github.com/linw7/Paper-Code/tree/master/code/52.二叉搜索树的第k大节点.cpp)|※| 63 | |53|二叉树的深度|[※](https://github.com/linw7/Paper-Code/tree/master/code/53.二叉树的深度.cpp)|※| 64 | |54|数组中数字出现的次数|[※](https://github.com/linw7/Paper-Code/tree/master/code/)|※| 65 | |55|和为s的数字|[※](https://github.com/linw7/Paper-Code/tree/master/code/55.和为s的数字.cpp)|※| 66 | |56|翻转字符串|[※](https://github.com/linw7/Paper-Code/tree/master/code/56.翻转字符串.cpp)|※| 67 | |57|队列的最大值|[※](https://github.com/linw7/Paper-Code/tree/master/code/)|※| 68 | |58|n个骰子的点数|※|※| 69 | |59|扑克牌中的顺子|※|※| 70 | |60|圆圈中最后剩下的数字|※|※| 71 | |61|股票的最大利润|※|※| 72 | |62|求1 + 2 + ......n|※|※| 73 | |63|不用加减乘除做加法|※|※| 74 | |64|构建乘积数组|※|※| 75 | --------------------------------------------------------------------------------