C++和Python面试经典算法汇总(一)

目录

  • [1. 开胃菜](#1. 开胃菜)
    • [1.1 交换连个变量的值](#1.1 交换连个变量的值)
    • [1.2 复制字符串](#1.2 复制字符串)
  • [2. 排序算法](#2. 排序算法)
    • [2.1 冒泡排序](#2.1 冒泡排序)
    • [2.2 快速排序](#2.2 快速排序)
  • [3. 二分查找](#3. 二分查找)
  • [4. 目标框过滤](#4. 目标框过滤)
  • [5. 最常考力扣题目:两数之和](#5. 最常考力扣题目:两数之和)
    • [4.1 极简](#4.1 极简)
    • [4.2 哈希](#4.2 哈希)

☀️暮春渐逝,浅夏初临。招聘的步履并未随春光落幕,仍伴着夏日凉风徐徐前行。

📺 当下科技日新月异,软硬件发展恰似鸟之双翼、车之双轮,相辅相成、缺一不可。硬件为软件赋予坚实的躯体与臂膀,软件则为硬件赋予灵动的逻辑与思想。软件开发的相关岗位,手写代码往往是必不可少的一环,愿这篇 C++ 与 Python 面试经典算法汇总,能为你的求职面试之路,添一份助力,增一份底气。

1. 开胃菜

1.1 交换连个变量的值

定义两个int类型的变量,然后分别通过指针和引用的方式交换两个数的值。

先来看看引用传值:

cpp 复制代码
#include <iostream>
using namespace std;
void my_swap(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}
int main()
{
    int main_a = 15, main_b = 11;
    my_swap(main_a, main_b);
    cout << "main_a: " << main_a << endl;
    cout << "main_b: " << main_b << endl;
    return 0;
}

再来看看指针传值:

cpp 复制代码
#include <iostream>
using namespace std;
void my_swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
int main()
{
    int main_a = 15, main_b = 11;
    my_swap(&main_a, &main_b);
    cout << "main_a: " << main_a << endl;
    cout << "main_b: " << main_b << endl;
    return 0;
}

和引用传值没有太大的区别,唯一需要注意的是,在my_swap函数中需要解引用。

值传递,指针传递,引用传递,是面试最常考的内容,区别如下:

  • 🍹值传递:传变量副本,函数里改不动外面实参
  • 🍹指针传递:传变量的地址,通过解引用改原值
  • 🍹引用传递:给变量起别名,操作别名就是操作原变量

在使用效果上:

📝引用:更安全,无空值、无野指针,语法简洁

📝指针:灵活但危险,容易空指针、越界、野指针

接下来,我们还可以用模板实现各种数据类型的数值交换:

引用传递:

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 通用模板交换 所有类型通吃
template<typename T>
void my_swap(T& a, T& b)
{
    T temp = a;
    a = b;
    b = temp;
}

int main()
{
    // int
    int x = 10, y = 20;
    my_swap(x, y);
    cout << x << " " << y << endl;

    // double
    double d1 = 1.1, d2 = 2.2;
    my_swap(d1, d2);
    cout << d1 << " " << d2 << endl;

    // string
    string s1 = "abc", s2 = "def";
    my_swap(s1, s2);
    cout << s1 << " " << s2 << endl;

    return 0;
}

指针传递:

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 模板 + 指针传参
template<typename T>
void my_swap(T* a, T* b)
{
    // 解引用操作原值
    T temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    // int 类型
    int x = 10, y = 20;
    my_swap(&x, &y);
    cout << x << " " << y << endl;

    // double 类型
    double d1 = 1.1, d2 = 2.2;
    my_swap(&d1, &d2);
    cout << d1 << " " << d2 << endl;

    // string 类型
    string s1 = "hello", s2 = "world";
    my_swap(&s1, &s2);
    cout << s1 << " " << s2 << endl;

    return 0;
}

1.2 复制字符串

将字符串temp_b的内容复制到长度不确定的字符串temp_a中。

程序很简单,但是要注意先改变目标字符串的大小,值之与源字符串相等

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
void string_copy(string& dest, const string& src)  // 必须引用!
{
    dest.resize(src.size());  // 先开空间!
    for (int i = 0; i < src.size(); i++) {
        dest[i] = src[i];
    }
}
int main()
{
    string temp_a = "";
    string temp_b = "hello world";
    string_copy(temp_a, temp_b);
    for(auto i: temp_a)
        cout << i;
    return 0;
}

2. 排序算法

一般面试中,最常见的就是冒泡和快排,不会考第三种排序,更多精彩的排序算法请参考:十大经典排序算法(C语言实现)

2.1 冒泡排序

最经典,最常用的排序算法

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
void bubbleSort(vector<int> &arr)
{
    int n = arr.size();
    int temp = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n - i - 1; j++)
        {
            if(arr[j] > arr[j+1])
            {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}
int main()
{
    vector<int> init_arr = {1, 3, 5, 89, 55};
    bubbleSort(init_arr);
    for(auto i: init_arr)
        cout << i << " ";
    return 0;
}

2.2 快速排序

核心考察:分治思想、递归、指针 / 列表操作

快排的核心是分治,选一个基准元素,把小于它的放左边,大于的放右边,再递归排序左右。时间复杂度是 O (nlogn),最坏会退化成 O (n²),工程里可以用三数取中优化基准选择。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

vector<int> quickSort(vector<int>& arr) {
    // 递归终止:长度 <=1 直接返回
    if (arr.size() <= 1)
        return arr;

    // 选中间元素当基准(和Python完全一样)
    int pivot = arr[arr.size() / 2];

    vector<int> left, mid, right;

    // 遍历分三组:小的、相等、大的
    for (int x : arr) {
        if (x < pivot)
            left.push_back(x);
        else if (x == pivot)
            mid.push_back(x);
        else
            right.push_back(x);
    }

    // 递归 + 拼接
    auto L = quickSort(left);
    auto R = quickSort(right);

    // 合并:左 + 中 + 右
    L.insert(L.end(), mid.begin(), mid.end());
    L.insert(L.end(), R.begin(), R.end());

    return L;
}

int main() {
    vector<int> arr = {10,7,8,9,1,5};
    auto res = quickSort(arr);

    for (int x : res) cout << x << " ";
    return 0;
}

for循环采用的是C++11新语法,其实以前那种老的方式也可以,合并过程如下图所示:

如果觉得insert需要用到迭代器,比较难懂,可以采用这种方法:

c 复制代码
#include <iostream>
#include <vector>
using namespace std;

vector<int> quickSort(vector<int>& arr) {
    if (arr.size() <= 1)
        return arr;

    int pivot = arr[arr.size() / 2];
    vector<int> left, mid, right;

    for (int x : arr) {
        if (x < pivot) left.push_back(x);
        else if (x == pivot) mid.push_back(x);
        else right.push_back(x);
    }

    vector<int> l = quickSort(left);
    vector<int> r = quickSort(right);

    // 拼接:最简单写法,谁都能看懂
    vector<int> res;
    for (int x : l) res.push_back(x);
    for (int x : mid) res.push_back(x);
    for (int x : r) res.push_back(x);

    return res;
}

int main() {
    vector<int> arr = {10,7,8,9,1,5};
    vector<int> res = quickSort(arr);

    // 打印:新语法,一行搞定
    for (int x : res) cout << x << " ";
    return 0;
}

python版本

python 复制代码
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

# 测试
arr = [10, 7, 8, 9, 1, 5]
print(quick_sort(arr))

3. 二分查找

核心考察:边界条件、循环 / 递归实现

二分查找的前提是数组有序,核心是不断缩小查找区间,时间复杂度是 O (logn),在处理有序数据集时效率很高,比如在车载日志或模型配置查找里很常用。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int binarySearch(vector<int>& arr, int target) {
    int left = 0;
    int right = arr.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2; // 避免溢出
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1; // 没找到
}

int main() {
    vector<int> arr = {1, 3, 5, 7, 9, 11};
    cout << binarySearch(arr, 7) << endl; // 输出3
    return 0;
}

python版本

python 复制代码
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

# 测试
arr = [1, 3, 5, 7, 9, 11]
print(binary_search(arr, 7)) # 输出3

4. 目标框过滤

核心考察:结构体 / 类定义、列表遍历、条件过滤

目标检测任务里很常见的预处理步骤,过滤掉置信度低的无效框,减少后续处理量。用结构体 / 类来封装检测框信息,在工程里更清晰,也方便后续做 NMS 或者坐标转换。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

// 检测框结构体
struct BBox {
    int x1, y1, x2, y2;
    float score;
    int class_id;
};

vector<BBox> filterBBox(vector<BBox>& boxes, float score_thresh) {
    vector<BBox> res;
    for (auto& box : boxes) {
        if (box.score >= score_thresh) {
            res.push_back(box);
        }
    }
    return res;
}

int main() {
    vector<BBox> boxes = {
        {10, 10, 50, 50, 0.9f, 0},
        {20, 20, 60, 60, 0.3f, 1},
        {30, 30, 70, 70, 0.8f, 0}
    };
    vector<BBox> filtered = filterBBox(boxes, 0.5f);
    cout << "过滤后框数量:" << filtered.size() << endl; // 输出2
    return 0;
}

Python版

python 复制代码
from dataclasses import dataclass
from typing import List

@dataclass
class BBox:
    x1: int
    y1: int
    x2: int
    y2: int
    score: float
    class_id: int

def filter_bbox(boxes: List[BBox], score_thresh: float) -> List[BBox]:
    return [box for box in boxes if box.score >= score_thresh]

# 测试
boxes = [
    BBox(10, 10, 50, 50, 0.9, 0),
    BBox(20, 20, 60, 60, 0.3, 1),
    BBox(30, 30, 70, 70, 0.8, 0)
]
filtered = filter_bbox(boxes, 0.5)
print(f"过滤后框数量:{len(filtered)}") # 输出2

5. 最常考力扣题目:两数之和

原题如下:

两数之和用哈希表可以把时间复杂度降到 O (n),空间复杂度 O (n),比暴力的 O (n²) 高效很多。这种用空间换时间的思路,在工程里很常用。

4.1 极简

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

vector<int> twoSum(vector<int>& nums, int target) {
    int n = nums.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (nums[i] + nums[j] == target) {
                return {i, j};
            }
        }
    }
    return {};
}

int main() {
    vector<int> nums = {2,7,11,15};
    vector<int> ans = twoSum(nums, 9);
    cout << ans[0] << " " << ans[1] << endl;
    return 0;
}

python版本

python 复制代码
def twoSum(nums, target):
    n = len(nums)
    for i in range(n):
        for j in range(i + 1, n):
            if nums[i] + nums[j] == target:
                return [i, j]

nums = [2,7,11,15]
print(twoSum(nums, 9))

4.2 哈希

C++版本

利用C++map容器存储数组具体数值与编号之间的对应关系,再在后续搜索中寻找存储的数值中有无与当前值相加为目标值的数值,如果有则直接返回,有效降低了算法的时间复杂度。

cpp 复制代码
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> map;
    for (int i = 0; i < nums.size(); i++) {
        int complement = target - nums[i];
        if (map.find(complement) != map.end()) {
            return {map[complement], i};
        }
        map[nums[i]] = i;
    }
    return {}; // 没找到
}

int main() {
    vector<int> nums = {2, 7, 11, 15};
    vector<int> res = twoSum(nums, 9);
    cout << res[0] << " " << res[1] << endl; // 输出0 1
    return 0;
}

python版本

python的字典与C++map类似,都是关联式容器。实现方式大同小异。

python 复制代码
def two_sum(nums, target):
    num_map = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in num_map:
            return [num_map[complement], i]
        num_map[num] = i
    return []

# 测试
nums = [2, 7, 11, 15]
print(two_sum(nums, 9)) # 输出[0, 1]
相关推荐
夜猫逐梦2 小时前
【逆向经验】一篇文章讲透为什么CE搜不到Python游戏的内存值
开发语言·python·游戏
淡海水2 小时前
【AI模型】模型量化技术详解
人工智能·算法·机器学习
Zik----2 小时前
CILP模型讲解
人工智能·python·多模态
炸膛坦客2 小时前
嵌入式 - 数据结构与算法:(1-1)数据结构 - 顺序表(Sequential List)
数据结构·算法·嵌入式
陈eaten2 小时前
汇编使用AES指令集实现AES解密
汇编·python·aes解密·aes指令集
水龙吟啸2 小时前
数据结构与算法随机复习–Day1
数据结构·c++·算法
SilentSamsara2 小时前
闭包的本质:Python 如何捕获自由变量
开发语言·python·青少年编程·pycharm
生成论实验室2 小时前
《事件关系阴阳博弈动力学:识势应势之道》第八篇:认知与反思关系——探索、定位与延续
人工智能·算法·架构·知识图谱·创业创新
十五年专注C++开发2 小时前
浅谈LLVM
开发语言·c++·qt·clang·llvm