2022年复试题

常见算法整理:DFS、贪心、快速选择、摩尔投票与滑动窗口

在算法题中,有一些高频且实用的经典方法。本文结合几个典型问题,系统整理这些算法的核心思想与代码实现,适合作为复习与面试参考。

一、判断一个数是3的幂次方

c++ 复制代码
#include<iostream>
#include<cmath> 
using namespace std;
int main(){
	int n;
	cin >> n;
	if(n <= 0){
		cout << "不是3的幂次方" << endl;
		return 0;
	}
	while(n % 3 == 0){
		n /= 3;
	} 
	if(n == 1){
		cout << "是3的幂次方" << endl;
		return 0;
	}
	cout << "不是3的幂次方" << endl;
	return 0;
}

二、贪心算法------最优解快速求解

📌 问题:用最少张数凑金额

核心思想

  • 每次优先使用最大面额

✅ 代码

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

int main(){
    vector<int> denominations = {100, 50, 20, 10, 5, 1};
    vector<int> count(6, 0);

    int amount;
    cin >> amount;

    for(int i = 0; i < 6; i++){
        count[i] = amount / denominations[i];
        amount %= denominations[i];
    }

    cout << "最少张数方案:" << endl;
    for(int i = 0; i < 6; i++){
        cout << denominations[i] << "元: " << count[i] << "张" << endl;
    }

    return 0;
}

🧠 总结

👉 贪心适合:标准货币系统(如人民币)


三、快速选择(QuickSelect)------找最大值

📌 问题:在无序数组中找最大值

核心思想

  • 利用快排 partition
  • 每次只递归一边(剪枝)

✅ 代码

cpp 复制代码
int findMax(int a[], int l, int r){
    if(l == r) return a[l];

    int i = l, j = r;
    int pivot = a[l];

    while(i < j){
        while(i < j && a[j] <= pivot) j--;
        while(i < j && a[i] >= pivot) i++;
        if(i < j) swap(a[i], a[j]);
    }
    swap(a[l], a[i]);

    return findMax(a, l, i);
}

快排的代码

c++ 复制代码
#include<iostream>
using namespace std;
void quickSort(int a[], int l, int r){
	if(l >= r) return;
	int i = l, j = r;
	int pivot = a[l];
	while(i < j){
		while(i < j && a[j] >= pivot) j--;
		while(i < j && a[i] <= pivot) i++;
		if(i < j) swap(a[i], a[j]);
	}
	swap(a[l], a[i]);
	quickSort(a, l, i - 1);
	quickSort(a, i + 1, r);
}
int main(){
	int n;
	cin >> n;
	int a[n];
	for(int i = 0; i < n; i++){
		cin >> a[i];
	}
	quickSort(a, 0, n - 1);
	for(int i = 0; i < n; i++){
		cout << a[i] << " ";
	}
	return 0;
}

🧠 总结

👉 本质:快排 + 剪枝 = 快速选择


四、摩尔投票法------多数元素问题

📌 问题:找出现次数 > n/2 的元素


✅ 代码

cpp 复制代码
int majorityElement(vector<int>& nums) {
    int candidate = 0, count = 0;

    for(int x : nums){
        if(count == 0){
            candidate = x;
            count = 1;
        }else if(x == candidate){
            count++;
        }else{
            count--;
        }
    }

    count = 0;
    for(int x : nums){
        if(x == candidate) count++;
    }

    return count > nums.size()/2 ? candidate : -1;
}

或者

c++ 复制代码
#include<iostream>
#include<unordered_map>
using namespace std;
int main(){
	unordered_map<int, int> cnt;
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		int x;
		cin >> x;
		cnt[x]++;
	}
	for(auto& c : cnt){
		if(c.second > n / 2){
			cout << c.first << endl;
		}
	}
	return 0;
}

🧠 核心思想

👉 相同+1,不同-1,最终剩下的就是候选人


五、滑动窗口------连续子数组问题

📌 问题:找所有连续正整数,使和为 n


✅ 代码

cpp 复制代码
int i = 1, j = 1, sum = 0;

while(i <= n/2){
    if(sum < n){
        sum += j++;
    }else if(sum > n){
        sum -= i++;
    }else{
        for(int k = i; k < j; k++){
            cout << k << " ";
        }
        cout << endl;
        sum -= i++;
    }
}

相关推荐
故事和你9124 分钟前
洛谷-数据结构1-1-线性表1
开发语言·数据结构·c++·算法·leetcode·动态规划·图论
脱氧核糖核酸__26 分钟前
LeetCode热题100——53.最大子数组和(题解+答案+要点)
数据结构·c++·算法·leetcode
脱氧核糖核酸__1 小时前
LeetCode 热题100——42.接雨水(题目+题解+答案)
数据结构·c++·算法·leetcode
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【线性扫描贪心】:数列分段 Section I
c++·算法·编程·贪心·csp·信奥赛·线性扫描贪心
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【线性扫描贪心】:分糖果
c++·算法·贪心算法·csp·信奥赛·线性扫描贪心·分糖果
_日拱一卒2 小时前
LeetCode:2两数相加
算法·leetcode·职场和发展
py有趣2 小时前
力扣热门100题之零钱兑换
算法·leetcode
董董灿是个攻城狮2 小时前
Opus 4.7 来了,我并不建议你升级
算法
自我意识的多元宇宙2 小时前
二叉树遍历方式代码解读(2迭代)
数据结构
无敌昊哥战神3 小时前
【保姆级题解】力扣17. 电话号码的字母组合 (回溯算法经典入门) | Python/C/C++多语言详解
c语言·c++·python·算法·leetcode