给定一个数组 X
和一个正整数 K
,请找出使表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果最接近于数组中位数的下标 i
。如果有多个 i
满足条件,请返回最大的 i
。
X
的元素均为正整数。n
取值范围:2 <= n <= 1000
。K
大于 0 且小于数组的大小。i
的取值范围:0 <= i < 1000
。N/2
的元素的值。[50, 50, 2, 3]
, 2
1
50
:数组 [50, 50, 2, 3]
排序后为 [2, 3, 50, 50]
,中位数为下标 2
的元素 50
。1
:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。48
最接近 50
,因此返回下标 1
。X
按元素值升序排列。N/2
的元素(N
为数组长度)。i
,计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果。i
开始的 K
个元素的差值。i
。i
满足条件,则返回最大的 i
。X[i] - X[i+1] - ... - X[i+K-1]
表示从 i
开始的 K
个元素的差值。i+K-1
不超过数组的边界。[50, 50, 2, 3]
, 2
计算中位数:
[2, 3, 50, 50]
。2
的元素 50
。计算结果:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。比较与中位数的差:
|0 - 50| = 50
|48 - 50| = 2
|-1 - 50| = 51
48
最接近 50
,因此返回下标 1
。本题要求通过计算数组中每个下标对应的表达式结果,找到最接近中位数的下标。解题的关键在于:
const readline = require('readline');
// 创建readline接口,设置输入输出流
const rl = readline.createInterface({
input: process.stdin, // 输入流为标准输入
output: process.stdout // 输出流为标准输出
});
// 监听每一行输入
rl.on('line', (input_str) => {
// 移除输入字符串中的方括号
input_str = input_str.replace("[", "").replace("]", "");
// 将输入字符串按逗号分割,并转换为数字数组
const input_arr = input_str.split(",").map(Number);
// n是数组的长度减1(最后一个元素是K)
const n = input_arr.length - 1;
// nums数组包含前n个元素
const nums = input_arr.slice(0, n);
// k是数组中的最后一个元素,表示要计算的元素个数
const k = input_arr[n];
// 创建nums的副本并进行排序以计算中位数
const sorted_nums = [...nums].sort((a, b) => a - b);
// 计算中位数:排序后的中间元素
const median = sorted_nums[Math.floor(n / 2)];
// 初始化最小差值为JavaScript的安全整数最大值
let minDiff = Number.MAX_SAFE_INTEGER;
// 初始化结果下标为-1
let result = -1;
// 遍历所有可能的起始下标i,范围从0到n-k
for (let i = 0; i <= n - k; i++) {
let count = nums[i]; // 初始化count为当前下标的元素
// 计算从i到i+k-1的元素差值
for (let j = i + 1; j < i + k; j++) {
count -= nums[j]; // 依次减去下标j对应的元素
}
// 计算当前count与中位数之间的绝对差值
const diff = Math.abs(count - median);
// 如果当前差值小于已知最小差值,则更新最小差值和结果下标
if (diff < minDiff) {
minDiff = diff;
result = i; // 更新结果下标为当前下标i
}
// 如果当前差值等于已知最小差值,则更新结果下标为较大的那个
else if (diff === minDiff) {
result = Math.max(result, i); // 保留较大的下标
}
}
// 输出最终结果下标
console.log(result);
// 关闭readline接口
rl.close();
});
readline
模块创建一个接口,用于读取标准输入。line
事件,当用户输入一行内容时触发回调函数。[]
,并按逗号 ,
分割字符串,得到字符串数组。input_arr
。n
是数组的长度减 1,因为最后一个元素是 K
。nums
是数组的前 n
个元素。k
是数组的最后一个元素,表示要计算的元素个数。sorted_nums
,作为 nums
的副本,并进行升序排序。sorted_nums[Math.floor(n / 2)]
。minDiff
为 Number.MAX_SAFE_INTEGER
,用于记录最小差值。result
为 -1
,用于记录最终结果。i
,计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果 count
。count
与中位数 median
的差的绝对值 diff
。diff
小于 minDiff
,则更新 minDiff
和 result
。diff
等于 minDiff
,则更新 result
为最大的下标。result
。readline
接口。X
和 K
的字符串,格式为 [X[0], X[1], ..., X[n-1], K]
。X[i] - X[i+1] - ... - X[i+K-1]
表示从 i
开始的 K
个元素的差值。i+K-1
不超过数组的边界。[50, 50, 2, 3], 2
输入处理:
input_arr = [50, 50, 2, 3, 2]
。nums = [50, 50, 2, 3]
,K = 2
。计算中位数:
sorted_nums = [2, 3, 50, 50]
。sorted_nums[2] = 50
。计算结果:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。比较与中位数的差:
|0 - 50| = 50
|48 - 50| = 2
|-1 - 50| = 51
48
最接近 50
,因此返回下标 1
。这段代码通过读取输入、计算中位数、遍历数组并计算表达式结果,最终找到最接近中位数的下标。代码逻辑清晰,注释详细,便于理解。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 创建 Scanner 对象,用于读取输入
Scanner in = new Scanner(System.in);
// 读取输入字符串,并移除方括号,然后按逗号分割
String[] input_str = in.nextLine().replace("[", "").replace("]", "").split(",");
// 获取数组的长度(减去1,因为最后一个元素是K)
int n = input_str.length - 1;
// 创建数组 nums,用于存储输入的数字
int[] nums = new int[n];
// 获取 K 的值(最后一个元素)
int k = Integer.valueOf(input_str[n]);
// 将输入的数字部分存入 nums 数组
for (int i = 0; i < n; i++) {
nums[i] = Integer.valueOf(input_str[i]);
}
// 创建 sorted_nums 数组,用于存储排序后的 nums 数组
int[] sorted_nums = Arrays.copyOf(nums, n);
// 对 sorted_nums 数组进行升序排序
Arrays.sort(sorted_nums);
// 计算中位数(排序后数组的中间元素)
int median = sorted_nums[n / 2];
// 初始化最小差值为最大整数
int minDiff = Integer.MAX_VALUE;
// 初始化结果为-1
int result = -1;
// 遍历数组,计算每个下标对应的表达式结果
for (int i = 0; i <= n - k; i++) {
// 初始化计数器为当前元素
int count = nums[i];
// 计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
for (int j = i + 1; j < i + k; j++) {
count -= nums[j];
}
// 计算当前结果与中位数的差的绝对值
int diff = Math.abs(count - median);
// 如果当前差值小于最小差值
if (diff < minDiff) {
minDiff = diff; // 更新最小差值
result = i; // 更新结果为当前下标
} else if (diff == minDiff) { // 如果当前差值等于最小差值
result = Math.max(result, i); // 更新结果为最大的下标
}
}
// 输出结果
System.out.println(result);
}
}
Scanner
读取输入的一行字符串。[]
,并按逗号 ,
分割字符串,得到字符串数组 input_str
。K
,其余元素是数组 X
的元素。nums
,用于存储输入的数字部分。input_str
中的数字部分转换为整数,并存入 nums
数组。sorted_nums
数组,作为 nums
的副本。sorted_nums
进行升序排序。sorted_nums[n / 2]
。minDiff
为最大整数,用于记录最小差值。result
为 -1
,用于记录最终结果。i
,计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果 count
。count
与中位数 median
的差的绝对值 diff
。diff
小于 minDiff
,则更新 minDiff
和 result
。diff
等于 minDiff
,则更新 result
为最大的下标。result
。X
和 K
的字符串,格式为 [X[0], X[1], ..., X[n-1], K]
。X[i] - X[i+1] - ... - X[i+K-1]
表示从 i
开始的 K
个元素的差值。i+K-1
不超过数组的边界。[50, 50, 2, 3], 2
输入处理:
input_str = ["50", "50", "2", "3", "2"]
。nums = [50, 50, 2, 3]
,K = 2
。计算中位数:
sorted_nums = [2, 3, 50, 50]
。sorted_nums[2] = 50
。计算结果:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。比较与中位数的差:
|0 - 50| = 50
|48 - 50| = 2
|-1 - 50| = 51
48
最接近 50
,因此返回下标 1
。这段代码通过读取输入、计算中位数、遍历数组并计算表达式结果,最终找到最接近中位数的下标。代码逻辑清晰,注释详细,便于理解。
# 读取输入字符串,移除方括号,并按逗号分割,得到一个字符串列表
input_str = input().replace("[", "").replace("]", "").split(",")
# 计算输入数组的长度,n是数组的元素数量,最后一个元素为K
n = len(input_str) - 1
# 将前n个元素转换为整数,构建整数数组nums
nums = [int(input_str[i]) for i in range(n)]
# 将最后一个元素转换为整数,作为K的值
k = int(input_str[n])
# 创建nums的副本,并对副本进行排序以计算中位数
sorted_nums = nums.copy()
sorted_nums.sort()
# 计算中位数:排序后下标为n//2的元素
median = sorted_nums[n // 2]
# 初始化最小差值为正无穷大,结果下标初始化为-1
minDiff = float('inf')
result = -1
# 遍历所有可能的起始下标i,范围为0到n-k
for i in range(n - k + 1):
count = nums[i] # 初始化count为当前下标的元素
# 计算从i到i+k-1的元素的差值
for j in range(i + 1, i + k):
count -= nums[j] # 依次减去下标j对应的元素
# 计算当前count与中位数之间的绝对差值
diff = abs(count - median)
# 如果当前差值小于已知最小差值,则更新最小差值和结果下标
if diff < minDiff:
minDiff = diff
result = i
# 如果当前差值等于已知最小差值,则更新结果下标为较大的那个
elif diff == minDiff:
result = max(result, i)
# 输出最终结果下标
print(result)
input()
函数读取输入的一行字符串。[]
,并按逗号 ,
分割字符串,得到字符串列表 input_str
。K
,其余元素是数组 X
的元素。input_str
中的前 n
个元素转换为整数,存入列表 nums
。input_str
的最后一个元素转换为整数,作为 K
的值。sorted_nums
列表,作为 nums
的副本。sorted_nums
进行升序排序。sorted_nums[n // 2]
。minDiff
为正无穷大,用于记录最小差值。result
为 -1
,用于记录最终结果。i
,计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果 count
。count
与中位数 median
的差的绝对值 diff
。diff
小于 minDiff
,则更新 minDiff
和 result
。diff
等于 minDiff
,则更新 result
为最大的下标。result
。X
和 K
的字符串,格式为 [X[0], X[1], ..., X[n-1], K]
。X[i] - X[i+1] - ... - X[i+K-1]
表示从 i
开始的 K
个元素的差值。i+K-1
不超过数组的边界。[50, 50, 2, 3], 2
输入处理:
input_str = ["50", "50", "2", "3", "2"]
。nums = [50, 50, 2, 3]
,K = 2
。计算中位数:
sorted_nums = [2, 3, 50, 50]
。sorted_nums[2] = 50
。计算结果:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。比较与中位数的差:
|0 - 50| = 50
|48 - 50| = 2
|-1 - 50| = 51
48
最接近 50
,因此返回下标 1
。这段代码通过读取输入、计算中位数、遍历数组并计算表达式结果,最终找到最接近中位数的下标。代码逻辑清晰,注释详细,便于理解。
#include
#include
#include
#include
#include
using namespace std;
int main() {
string input_str;
getline(cin, input_str); // 读取输入的一行字符串
// 移除字符串中的方括号 '[' 和 ']'
input_str.erase(remove(input_str.begin(), input_str.end(), '['), input_str.end());
input_str.erase(remove(input_str.begin(), input_str.end(), ']'), input_str.end());
vector<string> input_vec; // 声明一个字符串向量用于存储分割后的输入
size_t pos = 0; // 声明一个位置变量,用于查找逗号
string token; // 声明一个临时字符串,用于存储每个分割出的部分
// 循环查找并分割字符串
while ((pos = input_str.find(",")) != string::npos) { // 找到逗号位置
token = input_str.substr(0, pos); // 获取逗号前的子字符串
input_vec.push_back(token); // 将子字符串添加到向量中
input_str.erase(0, pos + 1); // 移除已处理的部分
}
input_vec.push_back(input_str); // 添加最后一个元素
int n = input_vec.size() - 1; // 计算有效元素的数量(最后一个元素是K)
vector<int> nums; // 声明一个整型向量用于存储数字
for (int i = 0; i < n; i++) {
nums.push_back(stoi(input_vec[i])); // 将字符串转换为整数并添加到nums中
}
int k = stoi(input_vec[n]); // 将最后一个元素转换为整数,作为K的值
// 创建nums的副本并进行排序以计算中位数
vector<int> sorted_nums = nums;
sort(sorted_nums.begin(), sorted_nums.end());
int median = sorted_nums[n / 2]; // 计算中位数
int minDiff = INT_MAX; // 初始化最小差值为整数的最大值
int result = -1; // 初始化结果下标为-1
// 遍历所有可能的起始下标i,范围从0到n-k
for (int i = 0; i <= n - k; i++) {
int count = nums[i]; // 初始化count为当前下标的元素
// 计算从i到i+k-1的元素差值
for (int j = i + 1; j < i + k; j++) {
count -= nums[j]; // 依次减去下标j对应的元素
}
int diff = abs(count - median); // 计算当前count与中位数之间的绝对差值
// 如果当前差值小于已知最小差值,则更新最小差值和结果下标
if (diff < minDiff) {
minDiff = diff;
result = i; // 更新结果下标为当前下标i
}
// 如果当前差值等于已知最小差值,则更新结果下标为较大的那个
else if (diff == minDiff) {
result = max(result, i); // 保留较大的下标
}
}
cout << result << endl; // 输出最终结果下标
return 0; // 返回0,表示程序正常结束
}
#include
#include
#include
#include
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b); // 排序比较函数
}
int main() {
char input_str[1000]; // 声明输入字符串
fgets(input_str, sizeof(input_str), stdin); // 读取一行输入
// 去掉字符串中的方括号 '[' 和 ']'
char *ptr = strchr(input_str, '[');
while (ptr) {
memmove(ptr, ptr + 1, strlen(ptr)); // 移除'['
ptr = strchr(input_str, '[');
}
ptr = strchr(input_str, ']');
while (ptr) {
memmove(ptr, ptr + 1, strlen(ptr)); // 移除']'
ptr = strchr(input_str, ']');
}
// 分割输入字符串
int nums[100]; // 假设最大长度为100
int n = 0, k = 0;
char *token = strtok(input_str, ",");
while (token) {
if (token[0] != '\0') {
if (n < 100) {
nums[n++] = atoi(token); // 转换为整数并存入数组
}
}
token = strtok(NULL, ",");
}
k = nums[n - 1]; // K的值是最后一个元素
n--; // 调整有效元素数量
// 复制并排序数组以计算中位数
int sorted_nums[100];
memcpy(sorted_nums, nums, n * sizeof(int));
qsort(sorted_nums, n, sizeof(int), compare);
int median = sorted_nums[n / 2]; // 计算中位数
int minDiff = INT_MAX; // 初始化最小差值为最大整数
int result = -1; // 初始化结果为-1
// 遍历数组
for (int i = 0; i <= n - k; i++) {
int count = nums[i]; // 初始化计数器为当前元素
for (int j = i + 1; j < i + k; j++) {
count -= nums[j]; // 计算当前表达式的值
}
int diff = abs(count - median); // 计算当前差值
if (diff < minDiff) { // 如果当前差值小于最小差值
minDiff = diff; // 更新最小差值
result = i; // 更新结果为当前下标
} else if (diff == minDiff) { // 如果当前差值等于最小差值
result = (result > i) ? result : i; // 更新结果为最大的下标
}
}
printf("%d\n", result); // 输出结果
return 0; // 返回0,表示程序正常结束
}
getline
(C++)或 fgets
(C)读取输入的一行字符串。[
和 ]
。,
分割字符串,得到数字和 K
的值。nums
。k
是数组的最后一个元素,表示要计算的元素个数。n
是数组的有效长度(nums
的长度减 1)。sorted_nums
,作为 nums
的副本,并进行升序排序。sorted_nums[n / 2]
。minDiff
为最大整数,用于记录最小差值。result
为 -1
,用于记录最终结果。i
,计算表达式 X[i] - X[i+1] - ... - X[i+K-1]
的结果 count
。count
与中位数 median
的差的绝对值 diff
。diff
小于 minDiff
,则更新 minDiff
和 result
。diff
等于 minDiff
,则更新 result
为最大的下标。result
。X
和 K
的字符串,格式为 [X[0], X[1], ..., X[n-1], K]
。X[i] - X[i+1] - ... - X[i+K-1]
表示从 i
开始的 K
个元素的差值。i+K-1
不超过数组的边界。[50, 50, 2, 3], 2
输入处理:
nums = [50, 50, 2, 3]
,K = 2
。计算中位数:
sorted_nums = [2, 3, 50, 50]
。sorted_nums[2] = 50
。计算结果:
i = 0
,结果为 50 - 50 = 0
。i = 1
,结果为 50 - 2 = 48
。i = 2
,结果为 2 - 3 = -1
。比较与中位数的差:
|0 - 50| = 50
|48 - 50| = 2
|-1 - 50| = 51
48
最接近 50
,因此返回下标 1
。这段代码通过读取输入、计算中位数、遍历数组并计算表达式结果,最终找到最接近中位数的下标。代码逻辑清晰,注释详细,便于理解。
华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。
机试是进入技术面的第一关:
华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。
技术面试需要手撕代码:
技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。
入职后的可信考试:
入职华为后,还需要通过“可信考试”。可信考试分为三个等级:
2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:
关注历年真题:
适应新题目:
掌握常见算法:
华为OD考试通常涉及以下算法和数据结构:
保持编程规范:
官方参考:
加入刷题社区:
寻找系统性的教程:
刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。
本地编写代码
调整心态,保持冷静
输入输出完整性
快捷键使用
Ctrl+D
,复制、粘贴和撤销分别为 Ctrl+C
,Ctrl+V
,Ctrl+Z
,这些可以正常使用。Ctrl+S
,以免触发浏览器的保存功能。浏览器要求
交卷相关
时间和分数安排
考试环境准备
技术问题处理 a
祝你考试顺利,取得理想成绩!