20240310-2-数组(Array)

news2024/9/29 1:26:13

数组(Array)

在这里插入图片描述

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

1. two sum

题目: 给你一个数组arr,和一个目标值target,找到一组下标(i,j)使得arri = target。
进阶: 数组中有重复的值,找到所有可能的下标组合。
例如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,使用两次同一个3
                    if(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] > target
            if(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和b
    int 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 --;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1506592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】线程封装_互斥

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;线程封装Thread.cpp &#x1f449;&am…

给 spyter/all-spark-notebook 添加scala支持

spyter/all-spark-notebook默认没有安装scala notebook&#xff0c;需要手动添加。 你可以创建一个新的 Dockerfile&#xff0c;在其中添加你需要的配置和组件。以下是一个简单的例子&#xff1a; FROM jupyter/all-spark-notebook:x86_64-ubuntu-22.04 #冒号后可以是latest&a…

Masked Generative Distillation(MGD)2022年ECCV

Masked Generative Distillation&#xff08;MGD&#xff09;2022年ECCV 摘要 **目前的蒸馏算法通常通过模仿老师的输出来提高学生的表现。本文表明&#xff0c;教师还可以通过引导学生特征恢复来提高学生的代表性。从这个角度来看&#xff0c;我们提出的掩模生成蒸馏&#x…

扩展学习|系统理解数字经济

文献来源&#xff1a;[1]肖静华,胡杨颂,吴瑶.成长品&#xff1a;数据驱动的企业与用户互动创新案例研究[J].管理世界,2020,36(03):183-205.DOI:10.19744/j.cnki.11-1235/f.2020.0041. [2]陈晓红,李杨扬,宋丽洁等.数字经济理论体系与研究展望[J].管理世界,2022,38(02):208-22413…

微信小程序跳转到其他小程序

有两种方式&#xff0c;如下&#xff1a; 一、appid跳转 wx.navigateToMiniProgram({appId: 目标小程序appid,path: 目标小程序页面路径,//不配的话默认是首页//develop开发版&#xff1b;trial体验版&#xff1b;release正式版envVersion: release, success(res) {// 打开成功…

yudao-cloud 学习笔记

前端代码 浏览器打开 https://cloud.iocoder.cn/intro/ F12 执行代码 var aaa $(".sidebar-group-items").find("a"); var ll[]; var tt[]; for(var i0;i<aaa.length;i ){ ll.push("https://doc.iocoder.cn" $(aaa[i]).attr("href&quo…

电动车窗开关中MOS管的应用解析

随着科技的不断发展&#xff0c;电动车窗系统已经成为现代汽车中不可或缺的一部分。而MOS&#xff08;金属氧化物半导体&#xff09;管的应用&#xff0c;为电动车窗开关注入了新的活力&#xff0c;极大地提高了其使用寿命和安全性。 一、MOS的优越性能 MOS管以其卓越的开关…

记录西门子:IO隔离SCL编程

在PLC变量中创建IO输入输出 在PLC类型中创建输入和输出&#xff0c;并将PLC变量的输入输出名称复制过来 创建一个FC块或者FB块 创建一个DB块 MAIN主程序中&#xff1a;

【JavaEE初阶系列】——计算机是如何工作的

目录 &#x1f388;冯诺依曼体系 ❗外存和内存的概念 ❗CPU中央处理器—人类当今科技领域巅峰之作之一 &#x1f6a9;如何衡量cpu &#x1f6a9;指令&#xff08;Instruction&#xff09; &#x1f388;操作系统&#xff08;Operating System&#xff09; &#x1f388;…

超越基础:提升你的数据采集策略与IP代理的高级应用

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

软件测试 需求

文章目录 1. 需求1.1 什么是需求1.2 为什么要有需求1.3 测试人员眼中的需求1.4 如何深入理解需求 2. 测试用例的概念2.1 什么是测试用例2.2 为什么要有测试用例 3. 软件错误&#xff08;BUG&#xff09;的概念4. 开发模型和测试模型4.1 软件的生命周期4.2 瀑布模型&#xff08;…

[SAP] ABAP注释快捷键修改

在使用ABAP编辑器的时候&#xff0c;原有的添加代码注释和取消代码注释的快捷键未生效&#xff0c;这时我们可以考虑对注释快捷键进行修改 在事务码SE38(ABAP编辑器)屏幕右下角&#xff0c;点击【Options选项】图标 在【键盘】|【命令】输入栏中输入"comment"关键字…

mac上更改vscode快捷键

以移动当前行代码为例 mac上的vscode&#xff0c;默认移动当前行代码的快捷键是⌥↑即option↑按键 现在我想改成command↑ 步骤如下 1.打开vscode-code-首选项-键盘快捷键 2.打开快捷键列表 3.输入move line&#xff0c;找到要改动的这个快捷键 当前行-右键-更改键绑定&…

LTspice(14) Noise仿真

LTspice(14) Noise仿真 好久没有更新LTspice的教程了&#xff0c;大家想了没&#xff1f; 截止目前LTspice已经更新到24.0.9。界面发生了一些变化&#xff0c;但主要功能并不受影响&#xff0c;新的版本改了UI&#xff0c;找东西更加方便了&#xff0c;界面如下图1所示。 图1…

JavaEE+springboot教学仪器设备管理系统o9b00-springmvc

本文旨在设计一款基于Java技术的教学仪器设备销售网站&#xff0c;以提高网站性能、功能完善、用户体验等方面的优势&#xff0c;解决现有教学仪器设备销售网站的问题&#xff0c;并为广大教育工作者和学生提供便捷的教学仪器设备销售渠道。本文首先介绍了Java技术的相关基础知…

checking file system on C

1、win7系统 开机检查C盘&#xff0c;虽然可以ESC取消检查&#xff0c;每次操作很麻烦&#xff0c;且没有意思 2、注册表清空BootExecute数值数据 1&#xff09;打开注册表 WinR &#xff08;快捷键&#xff09;输入“regedit”&#xff0c;回车 2&#xff09;位置HKEY_LOCAL…

怎么在运行框执行脚本和软件?

1.新建一个文件夹&#xff08;随便命名&#xff09; 2.右击此电脑点击属性 3.点击高级系统设置 4.点击环境变量 5.选中Path,点击编辑 6.点击编辑&#xff0c;粘贴你刚刚文件夹的地址 7.所有窗口全部点击确定 8.你可以把常用的软件快捷方式复制到文件夹里&#xff08;比如微…

QT画图功能

QT画图功能 每个QWidget都自带的功能&#xff0c;继承了QPainteDevice都可以使用QPainter来进行绘图。 画图需要调用paintEvent绘制事件&#xff0c;paintEvent事件时QWidget类自带的事件。 重写paintEvent事件。&#xff08;重写事件&#xff1a;如果父类有某个方法&#xff…

协程库项目—协程类模块

ucontext_t结构体、非对称协程 协程类 ucontext_t结构体 头文件中定义的四个函数&#xff08;getcontext(), setcontext(), makecontext(), swapcontext()&#xff09;和两个结构类型&#xff08;mcontext_t, ucontext_t&#xff09;在一个进程中实现用户级的线程切换。 其中…

MySQL进阶之(五)InnoDB数据存储结构之表空间

五、InnoDB数据存储结构之表空间 5.1 数据页加载的三种方式5.1.1 内存读取5.1.2 随机读取5.1.3 顺序读取 5.2 区5.2.1 为什么要有区&#xff1f;5.2.2 碎片区5.2.3 区的分类 5.3 段5.4 表空间5.4.1 独立表空间5.4.2 系统表空间 在数据页结构中提到过&#xff0c;页的上层结构中…