数组(Array)

面试中最常见的就是围绕数组进行出题,主要原则数组可以随机读取,一般遇到数组相关的题目,都不是直观看到的那样。第一步暴力解法,第二步是否可以排序,是否可以二分,是否可以使用数据结构(哈希表,队列,栈等)。
要时刻注意一个数组中有两列数,一列是给定的数组的值,另一个是数组的下标。

1. two sum

题目: 给你一个数组arr,和一个目标值target,找到一组下标(i,j)使得arriarr_iarri​+ arrjarr_jarrj​= targettargettarget。
进阶: 数组中有重复的值,找到所有可能的下标组合。
例如arr = [1, 2, 3, 3, 2, 4] target = 5。 return {(0, 5), (1, 2), (1, 3), (2, 4), (3, 4)}。
公司: 各大公司

pair<int, int> twosum(int *arr, int n, int target) {map<int, int> hash;pair<int, int> result;for(int i = 0; i < n; i++) {if(hash.find(arr[i]) == hash.end()) {hash[target - arr[i]] = i;}else {result = make_pair(hash[arr[i]], i);break;}}return result;
}vector<pair<int, int> > twosumplus(int *arr, int n, int target) {map<int, vector<int> > hash;for(int i = 0; i < n; i ++) {if(hash.find(arr[i]) == hash.end()) {vector<int> tmp;tmp.push_back(i);hash[arr[i]] = tmp;}else {hash[arr[i]].push_back(i);}}vector<pair<int, int> > results;for(int i = 0; i < n; i ++) {map<int, vector<int>>::iterator it = hash.find(target - arr[i]);if(it != hash.end()) {for(int j = 0; j < hash[target-arr[i]].size(); j ++) {for(int k = 0; k < hash[arr[i]].size(); k ++) {// 去除 3 + 3 = 6,使用两次同一个3if(target - arr[i] == arr[i] && k <= j) {continue;}int x = min(hash[target-arr[i]][j], hash[arr[i]][k]);int y = max(hash[target-arr[i]][j], hash[arr[i]][k]);results.push_back(make_pair(x, y));}}hash.erase(it);}}return results;
}

2. 查找旋转数组

题目: 排序数组(没有重复元素)根据未知旋转轴排序(例如,0 1 2 3 4 5 变成 3 4 5 0 1 2。给定一个目标值进行搜索,如果存在返回下标,不存在返回-1。
公司: 百度,头条等

int find(vector<int> &arr, int l, int r, int target) {if(l > r || arr.size() == 0) return -1;int index = -1;while(l <= r) {int mid = (l + r) / 2;if(arr[mid] == target) {index = mid;break;}else if(arr[mid] < target) {if(arr[r] >= target) l = mid + 1;else r = mid - 1;}else { // arr[mid] > targetif(arr[l] <= target) right = mid - 1;else left = mid + 1;}}return index;
}

3 主元素

题目: 给你一个证书数组,其中有一个数字出现了超过1/2,这个数就是主元素,请找出这个数字。
扩展1: 找到一个主元素,它出现的次数严格大于数组个数的1/3.
公司: 百度,京东

// 每次去掉两个数,剩下的那个就是主元素
int MainElem(int *arr, int n) {int mainelem = arr[0];int cnt = 1;for(int i = 1; i < n; i ++) {if(mainelem == arr[i]) {cnt ++;}else {cnt --;if(cnt == 0) {mainelem = arr[i];cnt = 1;}}}return mainelem;
}// 每次去掉三个数,选择两个候选集合
int MainElemP(int *arr, int n) {int maina, mainb, cnta, cntb;cnta = cntb = 1;maina = arr[0];mainb = arr[1];for(int i = 2; i < n; i ++) {if(arr[i] == maina) cnta ++;else if(arr[i] == mainb) cntb ++;else if(cnta == 0) {maina = arr[i];cnta = 1;}else if(cntb == 0) {mainb = arr[i];cntb = 1;}else { // 去掉三个数cnta --;cntb --;}}int cnt = 0;for(int i = 0; i < n; i ++) {if(minas == arr[i]) cnt ++;}if(cnt >= n / 3) return maina;else return mainb;
}

4. 落单的数

题目: 2n+1个数,其中只有一个数出现了一次,其他都出现了两次,求出这个出现一次的数。
扩展1: 2n+2个数,其中有两个出现一次,其他出现两次,求这两个出现一次的数。
扩展2: 3n+1个非负数,只有一个数出现了一次,其他都出现了三次,求出现一次的数。 公司: 常见的题目

// xor: a ^ 0 = a, a ^ a = 0
int SingleNumber(int *arr, int n) {int ans = 0;for(int i = 0; i  < n; i ++) {ans = ans ^ arr[i]}return ans;
}
// 找到a和b, 和上一个类似,
pair<int, int> SingleNumberP(int *arr, int n) {int c = 0;for(int i = 0; i  < n; i ++) {c = c ^ arr[i]}// c = a ^ b, 确定c的位数是1的位置。int k = 0;while(c) {if(c & 1) break;k ++;c =>> 1;}// 根据1的位置不同确定a和bint a = 0, b = 0;for(int i = 0; i < n; i ++) {if((arr[i]>>k) & 1) {a ^= arr[i];}else {b ^= arr[i];}}return make_pair(a, b);
}
// 非负整数,记录所有位的1的个数,对3取余即可
int SingleNumberPP(int *arr, int n) {int res = 0;  for(int j = 0; j < 32; j ++) {int bits = 0;for(int i = 0; i < n; i ++) {bits += (arr[i] >> j) & 1;}ans |= (bits % 3) << j;}return ans;
}

5. 中位数

题目: 给定两个有序数组,找到这两个数组合并排序后的中位数。
公司: 360,阿里

double findMedianSortedArrays(vector<int> &A, vector<int> &B) {// do A.size() < B.size()if(A.size() > B.size()) swap(A, B);int lena = A.size();int lenb = B.size();int la = 0, ra = lena, ma, mb, madian;while(la <= ra) {ma = (la + ra) / 2;mb = (lena + lenb + 1) / 2 - ma;if(ma < lena && mb > 0 && B[mb-1] > A[ma]) {la = ma + 1;}else if(ma > 0 && mb < lenb && B[mb] < A[ma-1]) {ra = ma - 1;}else {if(ma == 0) median = B[mb - 1];else if(mb == 0) median = A[ma - 1];else {median = max(A[ma - 1], B[mb - 1]);}break;}}if((lena + lenb) % 2 == 1) {return double(median);} if(ma == lena) {return (median + B[mb]) / 2.0;}if(mb == lenb) {return (median + A[ma]) / 2.0;}return (median + min(A[ma], B[mb])) / 2.0;
}

6. 二维数组中的查找

题目: 给你一个每一行每一列都有序的二维数组,给定一个target,查找这个值是否在二维数组中。
扩展1: 计算target出现的次数。
公司: 常见的题目

// 查找是否存在
bool SearchMatrix(vector<vector<int> > matrix, int target) {if(matrix.size() == 0) return false;int m = matrix.size(), n = matrix[0].size();int mid, low = 0, high = n * m - 1;while(low <= high) {mid = (low + high) / 2;int r = mid / n;int c = mid % n;if(matrix[r][c] == target) {return true;}else if(matrix[r][c] < target) {low = mid + 1;} else {high = mid - 1;}}return false;
}// 查找次数
int SearchMatrixP(vector<vector<int> > matrix, int target) {if(matrix.size() == 0) return 0;int m = matrix.size(), n = matrix[0].size();int i = m - 1, j = 0, cnt = 0;while(i >= 0 && j < n) {if(target == matrix[i][j]) {cnt ++;j ++;}else if(target > matrix[i][j]) {j ++;}else {i --;}}return cnt;
}

7. 构建乘积数组

题目: 给定一个数组A0, 1, …, n-1, 其中B中的元素Bix…xAi-1x…xA[n-1]。
公司: 某创业公司

// 从计算中可以直接使用数组的前缀和后缀乘积
vector<int> multiply(const vector<int>& arr1) {vector<int> arr2(arr1.size(), 0);// 计算前缀arr2[0] = 1;for(int i = 1; i < arr1.size(); i ++) {arr2[i] = arr2[i - 1] * arr1[i];}// 计算后缀int temp = 1;for(int i = arr1.size() - 2; i>= 0; i --) {temp *= arr1[i+1];arr2[i] *= temp;}return arr2;
}

8. 滑动窗口的最大值

题目: 给定一个数组array和滑动的大小k,求所有滑动窗口里的最大值。
公司: 头条

// 滑动窗口最大值
vector<int> MaxSildingWindow(vector<int> nums, int k) {deque<int> q;vector<int> ans;if(k <= 0) return ans;if(k == 1) return nums;for(int i = 0; i < k; i ++) {while(!q.empty() && nums[q.back()] <= nums[i]) {q.pop_back();}q.push_back(i);}for(int i = k; i < nums.size(); i ++) {ans.push_back(nums[q.front()]);while(!q.empty() && nums[q.back()] <= nums[i]) {q.pop_back();}if(!q.empty() && i - q.front >= k) { // 超过窗口大小q.pop_front();}q.push_back(i);}// 处理结尾ans.push_back(nums[q.front()]);return ans;
}

9. 第k小(大)的数

题目: 给你一个无序数组,找出第k小的数。
公司: 常见题目

int randPartition(int *arr,int l,int r){int x = arr[l];int i=l+1,j=r;while(i<j){while(arr[i]<x && i<r) i++;while(arr[j]>=x && j>l) j--;if(i<j){swap(arr[i],arr[j]);i++;j--;}}// 交换最后一个位置swap(arr[l],arr[j]);return j;
}
int kthSmallest(int *arr,int l,int r,int k){if(k<0 || k > r-l+1) return -1;int pos = randPartition(arr,l,r);// 使用相对位置if(pos-l+1 == k) return arr[pos];else if(pos-l+1 > k) return kthSmallest(arr,l,pos-1,k);else{//在右边,因为使用的是相对位置,所以k要减去左边丢弃的数的个数return kthSmallest(arr,pos+1,r,k-(pos-l+1));}
}
int findKElem(int *arr, int n, int k) {// 根据快速排序的思想,使用快排的一次划分if(n < 0 || arr == NULL) return -1;return kthSmallest(arr, 0, n-1, k);
}

10. 奇偶排序

题目: 给你一个数组,将所有的偶数排列奇数的前面。
公司: 搜狐

void oddEvenSort(vector<int> &arr) {int i = 0, j = arr.size() - 1;while(1) {while(i < j && a[i] % 2 == 0) i ++;while(i < j && a[j] % 2 == 1) j --;if(i > j) break;swap(arr[i], arr[j]);i ++, j --;}
}

Coding-数组(Array)相关推荐

  1. PIL中的Image和numpy中的数组array相互转换

    PIL中的Image和numpy中的数组array相互转换 array转换成image 1 Image.fromarray(np.uint8(img)) https://www.cnblogs.com ...

  2. 元组Tuple、数组Array、映射Map

    一.元组Tuple 元组Tuple是不同类型的值的聚集,元组的值将单个的值包含在圆括号中来构成,元组可以包含一个不同类型的元素 如 val riple = (100, "Scala" ...

  3. PHP删除数组(array一维)中指定的某个值 (转)

    2019独角兽企业重金招聘Python工程师标准>>> PHP删除数组(array一维)中指定的某个值  PHP删除数组(array一维)中指定的某个值 根据指定的值删除: $stu ...

  4. php 判断类型array,判断一个变量是数组Array类型的方法_javascript技巧

    在很多时候,我们都需要对一个变量进行数组类型的判断.JavaScript中如何判断一个变量是数组Array类型呢?我最近研究了一下,并分享给大家,希望能对大家有所帮助. JavaScript中检测对象 ...

  5. Java ArrayList和Vector、LinkedList与ArrayList、数组(Array)和列表集合(ArrayList)的区别...

    ArrayList和Vector的区别 ArrayList与Vector主要从二方面来说. 一.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的. ...

  6. php怎样解析数组,PHP 数组 Array 解析

    官方介绍 PHP 数组实际上是一个有序的映射(map),映射是一种把多个值(values)关联到对应的多个键(keys)的类型.这种映射类型在很多方面做了优化,因此可以把它当成真正的数组(就是上面说的 ...

  7. C语言实现数组Array(附完整源码)

    C语言实现数组Array 数组定义 实现以下18个接口 完整头文件 完整源文件 main 测试文件 数组定义 typedef struct CArray{int *array;int size;} C ...

  8. concat合并的数组会有顺序么_JS数组 Array

    Array​developer.mozilla.org JS没有真正数组,数组实际上是一种特殊的对象 创建数组的方法: let arr = [1,2,3]; // let arr = new Arra ...

  9. JAVA中数组Array与List互转

    List<String> list = new ArrayList<String>(); String[] array = new String[10]; Set<Str ...

  10. Python 列表list与数组array的区别

    1. 列表list与数组array的定义: 列表是由一系列按特定顺序排列的元素组成,可以将任何东西加入列表中,其中的元素之间没有任何关系: Python中的列表(list)用于顺序存储结构.它可以方便 ...

最新文章

  1. Java并发学习三:银行转账的死锁问题解决及示例
  2. 使Mybatis开发变得更加轻松的增强工具 — Ourbatis
  3. 突发流量引发的Dubbo拥堵,该怎么办?
  4. python测试开发自学教程-python测试开发学习笔记
  5. python拟牛顿法迭代点绘制_拟牛顿法python
  6. 深入理解es module
  7. spring cloud 入门系列六:使用Zuul 实现API网关服务
  8. python识别出蓝色_OpenCVPython——无法检测蓝色对象
  9. mysql5.5及以下安装全过程(5.7以上不适合)
  10. pandas.Series.values
  11. 110 同步、异步、阻塞、非阻塞
  12. Linux 开源词典工具及下载链接
  13. OSChina 周一乱弹 —— 程序猿到底是多有才?
  14. OneFlow源码解析:静态图与运行时
  15. NEAT(基于NEAT-Python模块)实现监督学习和强化学习
  16. 恶意软件分析实战02-分析3个恶意程序
  17. 电信增值业务学习笔记(转)
  18. Shell脚本攻略04-玩转文件描述符及重定向
  19. 选项菜单OptionMenu
  20. 外资撤离,为什么人民币会贬值,汇率下跌-货币总量和货币风险双重影响

热门文章

  1. CSS3关于过渡效果的问题
  2. Unix Linux大学教程(三):过滤器、正则表达式、vi
  3. C基础知识小总结(十)
  4. 各大IT公司笔试真题汇总开发人员一定要加入收藏夹的网站(收藏)
  5. 桌面图标不透明的小问题处理
  6. 神州6号发射成功了--庆祝一下
  7. 【怎样写代码】偷窥高手 -- 反射技术(二):窥视内部
  8. 比 GPT-3 更擅长理解用户意图,OpenAI发布 InstructGPT
  9. 深度强化学习的前景:帮助机器掌控复杂性
  10. 强化学习环境库 Gym 发布首个社区发布版,全面兼容 Python 3.9