2025华为OD机试题库(按算法分类):2025华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)。
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
感谢@on your left反馈,2025-04-01,A卷100分考试真题。
一、题目描述
给出数字K,请输出所有小于K的整数组合到一起的最小交换次数。
组合一起是指满足条件的数字相邻,不要求相邻后在数组中的位置。
取值范围:
-100 <= K <= 100
-100 <= 数组中的数值 <= 100
二、输入描述
第一行输入数组:1 3 1 4 0
第二行输入K数值:2
三、输出描述
第一行输出的最少交换次数:1
四、测试用例
测试用例1
1、输入
2 1 5 6 1
2
2、输出
1
3、说明
小于 2 的数字有 1, 1(共 2 个)。
滑动窗口法可得最少交换次数为 1。
测试用例2
1、输入
2 7 9 5 8 7 4
5
2、输出
1
3、说明
小于 5 的数字有 2, 4(共 2 个)。
通过滑动窗口法得到最小交换次数为 1。
五、解题思路
利用滑动窗口的思想,窗口大小为所有小于K的整数,然后窗口中大于K的整数是需要替换的次数。
详细解题思路
- 读取输入的整数数组和目标数值K;
- 统计数组中小于K的整数个数,记为count;
- 如果count为1,表示只有一个小于K的整数,不需要交换,直接输出0;
- 初始化最小交换次数minSwapCount为0;
- 遍历数组前count个元素,如果元素大于等于K,将minSwapCount加1;
- 将minSwapCount赋值给临时变量temp;
- 从第count个元素开始遍历数组,记当前元素为nums[j],前一个元素为nums[l],后一个元素为nums[r],其中l = j - count,r = j;
- 如果nums[l]大于等于K且nums[r]小于K,表示交换nums[l]和nums[r]可以减少一次交换次数,将temp减1;
- 如果nums[l]小于K且nums[r]大于等于K,表示交换nums[l]和nums[r]可以增加一次交换次数,将temp加1;
- 更新最小交换次数minSwapCount为min(minSwapCount, temp),保留较小的值;
- 输出最小交换次数minSwapCount;
六、Python算法源码
# 定义函数计算将所有小于K的数字组合在一起所需的最少交换次数
def min_swaps_to_group(nums, k):
# 统计数组中小于k的元素数量
count = sum(1 for num in nums if num < k)
# 如果没有或只有一个满足条件的数字,则无需交换
if count <= 1:
return 0
# 计算初始窗口(前count个元素)中不满足条件(>=k)的数字数量
bad = sum(1 for num in nums[:count] if num >= k)
min_swaps = bad # 初始化最小交换次数为初始窗口中的bad数量
# 使用滑动窗口遍历数组,窗口大小为count
for i in range(1, len(nums) - count + 1):
# 如果移出窗口的数字大于等于k,则bad数量减少1
if nums[i - 1] >= k:
bad -= 1
# 如果新进入窗口的数字大于等于k,则bad数量增加1
if nums[i + count - 1] >= k:
bad += 1
# 更新最小交换次数
min_swaps = min(min_swaps, bad)
return min_swaps
if __name__ == '__main__':
# 从输入中读取数字数组(空格分隔)
nums = list(map(int, input().split()))
# 从输入中读取k值
k = int(input())
# 输出最少交换次数
print(min_swaps_to_group(nums, k))
七、JavaScript算法源码
// 定义函数计算将所有小于K的数字组合在一起所需的最少交换次数
function minSwapsToGroup(nums, k) {
// 统计数组中小于k的元素数量
let count = nums.filter(num => num < k).length;
// 如果没有或只有一个满足条件的数字,则不需要交换
if (count <= 1) {
return 0;
}
// 计算初始窗口(前count个元素)中不满足条件(>=k)的数字数量
let bad = 0;
for (let i = 0; i < count; i++) {
if (nums[i] >= k) {
bad++;
}
}
let minSwaps = bad; // 初始化最小交换次数
// 使用滑动窗口遍历数组,窗口大小为count
for (let i = 1; i <= nums.length - count; i++) {
// 如果移出窗口的数字大于等于k,则bad数量减少1
if (nums[i - 1] >= k) {
bad--;
}
// 如果新进入窗口的数字大于等于k,则bad数量增加1
if (nums[i + count - 1] >= k) {
bad++;
}
// 更新最小交换次数
minSwaps = Math.min(minSwaps, bad);
}
return minSwaps;
}
// 示例:假设有输入字符串和K值(根据不同环境,可用prompt()等方式获取输入)
const inputLine = "1 3 1 4 0"; // 测试用例输入的数组字符串
const kValue = 2; // 测试用例K值
// 将输入字符串转换为数字数组
const nums = inputLine.split(" ").map(Number);
// 输出计算结果
console.log(minSwapsToGroup(nums, kValue));
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 函数:计算将所有小于K的数字组合在一起所需的最少交换次数
int minSwapsToGroup(int* nums, int n, int k) {
int count = 0;
// 统计数组中小于k的元素数量
for (int i = 0; i < n; i++) {
if (nums[i] < k)
count++;
}
// 如果没有或只有一个满足条件的数字,则无需交换
if (count <= 1)
return 0;
int bad = 0;
// 计算初始窗口(前count个元素)中不满足条件(>=k)的数字数量
for (int i = 0; i < count; i++) {
if (nums[i] >= k)
bad++;
}
int minSwaps = bad;
// 使用滑动窗口遍历数组,窗口大小为count
for (int i = 1; i <= n - count; i++) {
// 如果移出窗口的数字大于等于k,则bad数量减少1
if (nums[i - 1] >= k)
bad--;
// 如果新进入窗口的数字大于等于k,则bad数量增加1
if (nums[i + count - 1] >= k)
bad++;
if (bad < minSwaps)
minSwaps = bad;
}
return minSwaps;
}
int main() {
char line[1024];
// 从标准输入读取一行字符串(数组数字,以空格分隔)
fgets(line, sizeof(line), stdin);
int nums[1000];
int n = 0;
// 使用strtok分割字符串,转换为整数数组
char* token = strtok(line, " \n");
while (token != NULL) {
nums[n++] = atoi(token);
token = strtok(NULL, " \n");
}
int k;
// 读取K值
scanf("%d", &k);
// 计算最少交换次数并输出结果
printf("%d\n", minSwapsToGroup(nums, n, k));
return 0;
}
九、C++算法源码
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
// 函数:计算将所有小于K的数字组合在一起所需的最少交换次数
int minSwapsToGroup(const vector<int>& nums, int k) {
int n = nums.size();
int count = 0;
// 统计数组中小于k的元素数量
for (int num : nums) {
if (num < k)
count++;
}
// 如果没有或只有一个满足条件的数字,则不需要交换
if (count <= 1)
return 0;
int bad = 0;
// 计算初始窗口(前count个元素)中不满足条件(>=k)的数字数量
for (int i = 0; i < count; i++) {
if (nums[i] >= k)
bad++;
}
int minSwaps = bad;
// 使用滑动窗口遍历数组,窗口大小为count
for (int i = 1; i <= n - count; i++) {
// 如果移出窗口的数字大于等于k,则bad数量减少1
if (nums[i - 1] >= k)
bad--;
// 如果新进入窗口的数字大于等于k,则bad数量增加1
if (nums[i + count - 1] >= k)
bad++;
minSwaps = min(minSwaps, bad);
}
return minSwaps;
}
int main() {
string line;
// 从标准输入读取一行字符串(数字,以空格分隔)
getline(cin, line);
stringstream ss(line);
vector<int> nums;
int num;
// 将字符串中的数字读入vector中
while (ss >> num) {
nums.push_back(num);
}
int k;
// 读取K值
cin >> k;
// 输出最少交换次数
cout << minSwapsToGroup(nums, k) << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。