c++ 面试题(算法类)
1,从无序的数据流中找到其中位数:(用大根堆和小根堆来实现)
- float getMidimum(vector<int>& nums) {
- priority_queue<int> bigHeap; // 大数优先
- priority_queue<int, vector<int>, greater<int>> smallHeap; // 小数优先
- for (int i = ; i < nums.size(); ++i) { // 对每一个输入的元素
- if (bigHeap.empty() || nums[i] < bigHeap.top())
- bigHeap.push(nums[i]);
- else
- smallHeap.push(nums[i]);
- while (bigHeap.size() > smallHeap.size() + ) {
- smallHeap.push(bigHeap.top());
- bigHeap.pop();
- }
- while (smallHeap.size() > bigHeap.size() + ) {
- bigHeap.push(smallHeap.top());
- smallHeap.pop();
- }
- }
- float temp;// 如果两个堆大小相等
- if (bigHeap.size() == smallHeap.size()) {
- temp = float(bigHeap.top() + smallHeap.top()) / ;
- }
- else if (bigHeap.size() < smallHeap.size()) // 如果小堆多一个元素
- temp = smallHeap.top();
- else // 如果大堆多一个元素
- temp = bigHeap.top();
- return temp;
- }
getMidimum
2,25匹马五条赛道怎么最快选出前三个:(类似于:剑指offer p38::二维数组中的查找)
参考:https://blog.csdn.net/cmsbupt/article/details/17404183
3,给定出栈顺序,求入栈顺序:
给定入栈顺序,求出栈顺序:
- string Out; // 都声明未全局变量
- string In;
- bool match(string& In) {
- int lens = Out.length();
- stack<char> stk; // 模拟入栈操作
- stk.push(In[]);
- int j = , i = ; // j 为入栈序列索引, i 为出栈序列索引
- while (i < lens) { // 如果还没有匹配完所有出栈元素序列,则不断进行匹配,直到入栈序列结束
- if (j<lens && (stk.empty() || stk.top() != Out[i])) { // 如果入栈序列还有未进入栈的 && (栈空 || 不匹配)--》入栈操作
- stk.push(In[j]);
- ++j; // 指向下一个入栈元素
- }
- else if (stk.top() == Out[i]) {
- stk.pop();
- ++i;
- }
- else if (j == lens && !stk.empty()) { // 如果最后一个元素也遍历了,并且此时栈不空---》不是出栈顺序
- return false;
- }
- }
- return true;
- }
stackMatch
- int _tmain(int argc, _TCHAR* argv[])
- {
- // 给定一个栈的输出序列,找出所有可能的输入序列
- cout << "input outStack string[Enter]:";
- cin >> Out;
- In = Out;
- sort(In.begin(), In.end()); //求出所有的输入序列,排序的目的是从头开始进行全排列
- do {
- if (match(In)) // 该函数的功能是对 In 和 Out 进行匹配,传入的总是 In
- cout << In << endl;
- } while (next_permutation(In.begin(), In.end())); // 该函数的实现见前面leetcode 数组类型题的相关博客
- system("pause");
- return ;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- // 给定一个栈的输入序列,找出所有可能的输出序列
- cout << "input inStack string[Enter]:";
- cin >> In;
- Out = In;
- sort(Out.begin(), Out.end()); // 求出所有的输出序列
- do {
- if (match(In))
- cout << Out<< endl; // Out 是不断变化的
- } while (next_permutation(Out.begin(), Out.end())); //修改的是 Out 的本身
- system("pause");
- return ;
- }
main
4,给定以排好序的数组(包括负数,0,和正数),平方后找到其重复的元素(时间复杂度为 n,空间复杂度为 1)注:范围未知道
- void show(vector<int>& result) {
- for (int i = ; i<result.size(); ++i)
- cout << '\t' << result[i];
- cout << endl;
- }
- vector<int> dupNums(vector<int>& nums) {
- vector<int> result;
- for (int i = ; i<nums.size(); ++i)
- nums[i] *= nums[i];
- show(nums);
- vector<int>::iterator start = nums.begin();
- vector<int>::iterator end = nums.end() - ;
- while (start != end) {
- bool dup = false;
- if (*start < *end) {
- while ((end - ) != start) {
- if (*(end - ) == *end) {
- end--;
- dup = true;
- }
- else {
- break;
- }
- } // while2
- if (start != (end - ) && dup) {
- result.push_back(*end);
- end--;
- }
- else if (start != (end - ) && !dup){
- end--;
- }
- // show(result);
- if (end - == start) {
- if (*end == *start) {
- result.push_back(*start);
- }
- return result;
- }
- }//if
- else if (*start > *end) {
- while (start + != end) {
- if (*(start + ) == *start) {
- start++;
- dup = true;
- }
- else {
- start++;
- break;
- }
- }//while2
- if (start + != end && dup) {
- result.push_back(*start);
- start++;
- }
- if (start + != end && !dup) {
- start++;
- }
- if (start + == end) {
- if (*start == *end) {
- result.push_back(*start);
- }
- return result;
- }
- }//else if
- else {
- while (start + != end) {
- if (*(start + ) == *start) {
- start++;
- }
- else {
- result.push_back(*start);
- start++;
- break;
- }
- }
- if (start + == end) {
- return result;
- }
- while ((end - ) != start) {
- if (*(end - ) == *end) {
- end--;
- }
- else {
- end--;
- break;
- }
- }//while2
- if (end - == start) {
- if (*start == *end) {
- result.push_back(*start);
- }
- return result;
- }
- }//else
- }//while1
- return result;
- }
dupNums
类似题:给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次。找到所有出现两次的元素。空间复杂度为 1。注:范围已知
思路:把 nums[i] 放到 nums[nums[i] - 1] 的位置去(swap 操作)eg:把 4 放到下标为 3 的位置,把 5 放到下标为 4 的位置。
https://blog.csdn.net/zhangbaoanhadoop/article/details/82193866
5,skip_list(跳跃表):
https://blog.csdn.net/ict2014/article/details/17394259
6,快排(递归):
- //quickSort
- int Partition(int* arr, int left, int right) {
- int pivot = arr[left];
- while (left < right) {
- while (left < right && arr[right] >= pivot)
- --right;
- if (left < right) arr[left] = arr[right];
- while (left < right && arr[left] <= pivot)
- ++left;
- if (left < right) arr[right] = arr[left];
- }
- arr[left] = pivot;
- return left; // 返回枢纽值所在下标
- }
- void quickSort(int* arr, int left, int right) {
- int pivot = ;
- if (left <= right) {
- pivot = Partition(arr, left, right);
- quickSort(arr, left, pivot - );
- quickSort(arr, pivot + , right);
- }
- }
quickSort
快排(非递归,用栈来实现)
- void QuickSort(int *a, int left,int right)
- {
- if (a == NULL || left < || right <= || left>right)
- return;
- stack<int>temp;
- int i, j;
- //(注意保存顺序)先将初始状态的左右指针压栈
- temp.push(right);//先存右指针
- temp.push(left);//再存左指针
- while (!temp.empty())
- {
- i = temp.top();//先弹出左指针
- temp.pop();
- j = temp.top();//再弹出右指针
- temp.pop();
- if (i < j)
- {
- int k = Pritation(a, i, j);
- if (k > i)
- {
- temp.push(k - );//保存中间变量
- temp.push(i); //保存中间变量
- }
- if (j > k)
- {
- temp.push(j);
- temp.push(k + );
- }
- }
- // 参考:http://www.cnblogs.com/ljy2013/p/4003412.html
quickSort(非递归)
快排时间复杂度分析:https://www.cnblogs.com/surgewong/p/3381438.html
快排的几种优化方式:https://blog.csdn.net/sofia_m/article/details/81534390
快排是不稳定的排序算法,那么稳定的意义是什么呢?
答:当有多个字段需要排序时(比如书籍的销量和书籍的价格),我们可以先用稳定排序对价格(从低到高)进行排序,然后在用稳定排序对书籍的销量进行排序,这样排序的结果就是相同销量的数据价格低的排在前面,达到了在第一列排序的基础上排序了第二列。
7,堆排序:
- //heapSort
- void Swap(int& a, int& b) {
- int temp = a;
- a = b;
- b = temp;
- }
- //向上调整
- void siftUp(int* arr, int u) {
- int c, p; // c == child , p == parent
- c = u;
- for (;;) {
- if (c == ) break;
- p = c / ;
- if (arr[p] > arr[c]) break;
- Swap(arr[c], arr[p]);
- c = p;
- }
- }
- // 向下调整
- void siftDown(int* arr, int l, int u) {
- int c, p;
- p = l;
- for (;;) {
- c = * p;
- if (c > u) break;
- if (c + <= u && arr[c + ] > arr[c]) c++;
- if (arr[p] > arr[c]) break;
- Swap(arr[p],arr[c]);
- p = c;
- }
- }
- // 向上调整建大根堆
- void BuildBigHeap(int* arr,int n) {
- for (int i = ; i <= n; ++i)
- siftUp(arr, i);
- }
- //向下调整建大根堆
- void BuildHeap(int* arr, int n) {
- for (int i = n / ; i >= ; --i)
- siftDown(arr, i, n);
- }
- void heapSort(int* arr, int n) {
- int i = ;
- arr--;
- BuildBigHeap(arr, n);
- for (i = n; i >= ; --i) {
- Swap(arr[], arr[n]);
- siftDown(arr, , i - );
- }
- arr++;
- }
heapSort
8,二分搜索
- // 二分搜索
- // @没有重复值
- int binSearch(vector<int>& nums, int target) {
- auto left = nums.begin();
- auto right = nums.end()-;
- while (left <= right) { // 找mid 的对应值,此时 = 号不能忽略,否则 mid 取不到所有值
- auto mid = left + (right - left) / ;// 把搜索范围缩小到 right = left or right = left+1,此时 mid = left
- if (*mid == target)
- return distance(nums.begin(), mid);
- if (*mid < target)
- left = mid + ;
- if (*mid > target)
- right = mid - ;
- }
- return -;
- }
- //@ 有重复值,且返回匹配数 key 的最小下标,等同于 std::lower_bound (返回第一个大于等于 key 的迭代器)
- int binSearchDupMinIndex(vector<int>& nums, int target) {
- int left = ;
- int right = nums.size() - ;
- while (left <= right) { // 找mid 的对应值,此时 = 号不能忽略,否则 mid 取不到所有值
- int mid = left + (right - left) / ;// 把搜索范围缩小到 right = left or right = left+1,此时 mid = left
- if (nums[mid] < target)
- left = mid + ;
- else if (nums[mid] == target){ // 加以特殊处理
- if (mid - >= && nums[mid - ] == target)
- right = mid - ;
- else
- return mid;
- }
- else {
- right = mid - ;
- }
- }
- return -;
- }
- //@ 有重复值,且返回匹配数 key 的最大下标,等同于std::upper_bound(返回第一个大于 key 的元素的迭代器)
- int binSearchDupMaxIndex(vector<int>& nums, int target) {
- int left = ;
- int right = nums.size() - ;
- while (left <= right) { // 找mid 的对应值,此时 = 号不能忽略,否则 mid 取不到所有值
- int mid = left + (right - left) / ;// 把搜索范围缩小到 right = left or right = left+1,此时 mid = left
- if (nums[mid] < target)
- left = mid + ;
- else if (nums[mid] == target){ // 加以特殊处理
- if (mid + <= right && nums[mid + ] == target)
- left = mid + ;
- else
- return mid;
- }
- else {
- right = mid - ;
- }
- }
- return -;
- }
- // [4,5,1,2,3] 旋转数组的二分查找
- // @ 无重复值
- int binFind(vector<int>& nums, int target) {
- int left = ;
- int right = nums.size() - ;
- while (left <= right) {
- int mid = left + (right - left) / ;
- if (nums[mid] == target)
- return mid;
- else if (nums[left] <= nums[mid]) { // mid in left side 递减序列
- if (nums[left] <= target && target < nums[mid]) // left---target----mid
- right = mid - ;
- else // left---mid---target
- left = mid + ;
- }
- else { // mid in right side 递增序列
- if (nums[mid] < target && target <= nums[right]) // mid---target---right
- left = mid + ;
- else // target---mid---right
- right = mid - ;
- }
- }
- return -;
- }
- // @有重复值
- // 包含重复元素的数组 A = [1,3,1,1,1],当A[m] >= A[left]时,不能确定target 在left side
- // 拆分成两个条件:
- //(1)若:A[mid] > A[left],则区间 [left,mid] 一定递增
- //(2)若 A[mid] == A[left],确定不了,那就 left++,除去此元素再进行此查找过程
- int binFindDup(vector<int>& nums, int target) {
- int left = ;
- int right = nums.size() - ;
- while (left <= right) {
- int mid = left + (right - left) / ;
- if (nums[mid] == target)
- return mid;
- else if (nums[left] < nums[mid]) { // mid in left side 递减序列
- if (nums[left] <= target && target < nums[mid]) // left---target----mid
- right = mid - ;
- else // left---mid---target
- left = mid + ;
- }
- else if(nums[left] > target){ // mid in right side 递增序列
- if (nums[mid] < target && target <= nums[right]) // mid---target---right
- left = mid + ;
- else // target---mid---right
- right = mid - ;
- }
- else { // 把这个元素除去搜索范围
- //skip duplicate one
- left++;
- }
- }
- return -;
- }
binSearch
9,给定一个数组a,O(n)时间求 a[j] - a[i] 的最大值?
https://blog.csdn.net/xiaofengcanyuelong/article/details/78965552
c++ 面试题(算法类)的更多相关文章
- 前端面试题之一JAVASCRIPT(算法类)
一.JS操作获取和设置cookie //创建cookie function setcookie(name, value, expires, path, domain, secure) { var co ...
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- 关于面试题 Array.indexof() 方法的实现及思考
这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...
- 对Thoughtworks的有趣笔试题实践
记得2014年在网上看到Thoughtworks的一道笔试题,当时觉得挺有意思,但是没动手去写.这几天又在网上看到了,于是我抽了一点时间写了下,我把程序运行的结果跟网上的答案对了一下,应该是对的,但是 ...
- 从阿里巴巴笔试题看Java加载顺序
一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...
- JAVA面试题
在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...
- C++常考面试题汇总
c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...
- .NET面试题系列[4] - C# 基础知识(2)
2 类型转换 面试出现频率:主要考察装箱和拆箱.对于有笔试题的场合也可能会考一些基本的类型转换是否合法. 重要程度:10/10 CLR最重要的特性之一就是类型安全性.在运行时,CLR总是知道一个对象是 ...
- 我们公司的ASP.NET 笔试题,你觉得难度如何
本套试题共8个题,主要考察C#面向对象基础,SQL和ASP.NET MVC基础知识. 第1-3题会使用到一个枚举类,其定义如下: public enum QuestionType { Text = , ...
随机推荐
- hive入门学习线路指导
hive被大多数企业使用,学习它,利于自己掌握企业所使用的技术,这里从安装使用到概念.原理及如何使用遇到的问题,来讲解hive,希望对大家有所帮助.此篇内容较多:看完之后需要达到的目标1.hive是什 ...
- : LDAP & Implementation
LDAP LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP.它是基于X.500标准的,但是简单多了并且可以根据需要 ...
- SQLServer调WebService & 错误解决:请求格式无法识别
(sqlServer 2008 + VS2010) 首先,对服务器进行配置. sp_configure ; GO RECONFIGURE; GO sp_configure ; GO RECONFIGU ...
- zombodb 数据类型映射
zombodb 与es 数据类型的映射处理 通用数据类型映射 Postgres 类型 Elasticsearch JSON 映射定义 bytea {"type": "bi ...
- oracle错误汇总1
这是遇见的第一个整个库正常,但某张表查询报错的情况 某张表数据可以查,但一排序查就报错 select * from acct_daily_bak; select * from acct_daily_b ...
- 三、tcp、ip协议详细
1. 什么是 TCP/IP? TCP/IP 是一类协议系统,它是用于网络通信的一套协议集合. 传统上来说 TCP/IP 被认为是一个四层协议 1) 网络接口层: 主要是指物理层次的一些接口,比如电缆等 ...
- 集合总结三(HashMap的实现原理)
一.概述 二话不说,一上来就点开源码,发现里面有一段介绍如下: Hash table based implementation of the Map interface. This implement ...
- vim 简单实用
http://www.runoob.com/linux/linux-vim.html 编辑模式 : (同时打开两个文件) vim test.c test1.c -O 同时编辑两个文件 - ...
- ehcache讲解及实例
ehcache讲解及实例https://www.cnblogs.com/coprince/p/5984816.html 有些情形下注解式缓存是不起作用的:同一个bean内部方法调用,子类调用父类中有缓 ...
- Day 05 可变不可变、数据类型内置方法
1.可变类型:值改变,但是id不变,证明就是改变原值,是可变类型 2.不可变类型:值改变,但是id也跟着改变,证明是产生新的值,是不可变类型 数字类型 一.整型int 1.用途:记录年龄.等级.数量 ...