2023华为od机试题以及答案解析

求字符串中所有整数的最小和

输入字符串 s,输出 s 中包含所有整数的最小和说明:
字符串 s,只包含 a-z A-Z ± ;
合法的整数包括:
1) 正整数 一个或者多个 0-9 组成,如 0 2 3 002 102
2)负整数 负号 - 开头,数字部分由一个或者多个 0-9 组成

使用JavaScript的正则表达式和数组方法来实现。以下是一个示例代码:

function minSumOfIntegers(s) {// 使用正则表达式匹配所有整数(正整数和负整数)const numbers = s.match(/-?\d+/g) || [];// 将匹配到的字符串数组转换为整数数组,然后计算总和const totalSum = numbers.reduce((sum, num) => sum + parseInt(num, 10), 0);return totalSum;
}// 示例字符串
const s = "a1b2c-3d-002e102f";
console.log(minSumOfIntegers(s));

这段代码首先使用match方法和正则表达式/-?\d+/g来找到所有的整数字符串,然后使用reduce方法遍历这些字符串,把它们转换成整数并累加求和。如果字符串中没有找到任何整数,match方法会返回null,这时候通过|| []确保numbers是一个空数组,以避免在调用reduce方法时出错。最后,输出累加的结果。

IPv4地址转换为整数

将IPv4地址转换为整数的过程是将每个IPv4地址的四个部分(由点分隔)转换为二进制表示,并将它们拼接在一起,然后将这个二进制表示的数转换为十进制整数。下面是一个JavaScript函数,可以实现IPv4地址到整数的转换:

function ipv4ToInteger(ip) {const parts = ip.split('.'); // 将IPv4地址按照点分割成四个部分// 将每个部分转换为8位二进制数,然后拼接在一起const binary = (parseInt(parts[0]) << 24) +(parseInt(parts[1]) << 16) +(parseInt(parts[2]) << 8) +parseInt(parts[3]);return binary >>> 0; // 使用无符号右移将负数转换为正数
}// 示例用法
const ipv4Address = '192.168.1.1';
const integerRepresentation = ipv4ToInteger(ipv4Address);
console.log(integerRepresentation);

这个函数会将IPv4地址 '192.168.1.1' 转换为整数表示。

求二叉树的最小叶子节点下标

二叉树也可以用数组来存储,给定一个数组,树的根节点的值存储在下标1,对于存储在下标N的节点,他的左子节点和右子节点分别存储在下标2给定一个数组存储的二叉树,试求从根节点到最小的叶子节点的路径,路径由节点的值组成。

解析

为了解决这个问题,我们可以编写一个 JavaScript 函数来寻找从根节点到最小叶子节点的路径。在数组存储的二叉树中,对于存储在下标 N 的节点,其左子节点存储在下标 2*N,右子节点存储在下标 2*N + 1。我们可以使用递归方法来遍历这棵树,并记录当前的路径,当我们到达叶子节点时,比较当前叶子节点的值与已知的最小值,如果更小,更新路径。

以下是实现此逻辑的JavaScript代码:

function findPathToSmallestLeaf(arr) {let minPath = [];let minValue = Infinity;function dfs(index, path) {// 越界或者节点为空时返回if (index >= arr.length || arr[index] === null) {return;}// 将当前节点加入路径path.push(arr[index]);// 检查是否为叶子节点if (index * 2 >= arr.length || (arr[index * 2] === null && arr[index * 2 + 1] === null)) {// 更新最小值和路径if (arr[index] < minValue) {minValue = arr[index];minPath = [...path];}} else {// 递归遍历左右子节点dfs(index * 2, path);dfs(index * 2 + 1, path);}// 回溯,移除当前节点path.pop();}dfs(1, []); // 从根节点开始遍历return minPath;
}// 示例
const arr = [null, 1, 2, 3, 4, 5, 6]; // 使用 null 占位数组第一个元素,以使得根节点从下标1开始
console.log(findPathToSmallestLeaf(arr));

请注意,这段代码中数组的第一个元素是 null,这是为了使得根节点可以从下标 1 开始,这样对于存储在下标 N 的节点,其左子节点和右子节点分别存储在下标 2*N2*N+1,符合题目的要求。此代码在遇到叶子节点时检查其值是否为当前已知的最小值,并在是的情况下更新路径。这确保了最终的路径是到达值最小的叶子节点的路径。

数组去重和排序

给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。

解析

针对这个问题,我们可以使用JavaScript来解决。以下是一个分步解决方案:

  1. 统计元素出现的次数:遍历数组,使用一个对象(或Map)来统计每个元素出现的次数。
  2. 删除重复元素:这一步在统计的同时已经完成,因为对象(或Map)的键是唯一的。
  3. 根据出现次数和首次出现顺序排序:首先根据出现次数对元素进行排序,如果两个元素出现次数相同,则根据它们首次出现的顺序来排序,这需要我们在统计时额外记录每个元素首次出现的索引。

下面是实现这个算法的JavaScript代码示例:

function sortArrayByFrequencyAndOrder(arr) {const frequencyMap = new Map(); // 用于统计每个元素出现的次数const firstOccurrence = new Map(); // 用于记录每个元素首次出现的索引// 遍历数组,填充frequencyMap和firstOccurrencearr.forEach((element, index) => {if (!frequencyMap.has(element)) {frequencyMap.set(element, 1);firstOccurrence.set(element, index);} else {frequencyMap.set(element, frequencyMap.get(element) + 1);}});// 将Map转换为数组,以便进行排序const sortedArray = Array.from(frequencyMap).sort((a, b) => {// 如果出现次数不同,按次数降序排序if (b[1] !== a[1]) {return b[1] - a[1];}// 出现次数相同,按首次出现的索引升序排序return firstOccurrence.get(a[0]) - firstOccurrence.get(b[0]);});// 提取排序后的元素return sortedArray.map(item => item[0]);
}// 示例
const arr = [5, 3, 1, 2, 2, 3, 4, 4, 4];
console.log(sortArrayByFrequencyAndOrder(arr));

这段代码首先统计了数组中每个元素的出现次数,并记录了它们首次出现的位置。然后,它根据元素的出现次数和首次出现的索引进行排序,最后返回一个新数组,其中包含了按照指定规则排序的元素。

根据值求长度最长的序列

有N个正整数组成的一个序列。给定整数sum,求长度最长的连续。

解析

给定一个正整数数组和一个特定的整数 sum,寻找长度最长的连续子数组,其和等于 sum。下面是一个使用 JavaScript 实现的算法:

function findLongestSubarrayBySum(arr, sum) {let maxLength = 0; // 存储最长子数组的长度let currentSum = 0; // 当前子数组的和let start = 0; // 滑动窗口的起始索引let bestRange = [-1, -1]; // 存储最长子数组的起始和结束索引for (let end = 0; end < arr.length; end++) {currentSum += arr[end]; // 将当前元素加到当前和中// 当当前和超过目标和时,移动起始索引直到当前和小于或等于目标和while (currentSum > sum && start < end) {currentSum -= arr[start];start++;}// 如果当前和等于目标和且当前子数组的长度大于之前存储的最长长度,则更新最长长度和最佳范围if (currentSum === sum && (end - start + 1) > maxLength) {maxLength = end - start + 1;bestRange = [start, end];}}// 如果没有找到符合条件的子数组,则返回空数组if (bestRange[0] === -1) return [];// 根据最佳范围返回最长子数组return arr.slice(bestRange[0], bestRange[1] + 1);
}

这个算法的核心是滑动窗口技术。它从数组的左端开始,用两个指针(startend)表示当前考虑的子数组的边界。随着算法的进行,end 指针向右移动以增加子数组的和,当子数组的和超过目标和时,start 指针向右移动以减少子数组的和。当找到一个和等于目标和的子数组时,检查其长度是否是目前发现的最长的,并相应地更新最长子数组的信息。

请注意,此算法假设数组中所有的数字都是正整数。这是因为,如果数组中包含负数或零,当前和可能在不增加子数组长度的情况下减少,这会使问题变得更加复杂。

员工出勤信息

为了解决这个问题,我们可以编写一个 JavaScript 函数来处理考勤信息并根据给定条件判断员工是否符合获得出勤奖的资格。算法的实现步骤大致如下:

  1. 遍历考勤记录数组,统计缺勤次数,并检查是否存在连续的迟到/早退。
  2. 使用一个滑动窗口(大小为7)遍历考勤记录数组,检查任意连续7次考勤中,缺勤/迟到/早退的次数是否超过3次。
  3. 根据上述检查的结果,输出员工是否能获得出勤奖。

下面是具体的实现代码:

function canGetAttendanceAward(attendanceRecords) {let absentCount = 0; // 缺勤次数let continuousLateLeaveEarly = false; // 连续迟到/早退标志// 检查连续迟到/早退和总缺勤次数for (let i = 0; i < attendanceRecords.length; i++) {if (attendanceRecords[i] === 'absent') {absentCount++;}if (i > 0 && ((attendanceRecords[i] === 'late' || attendanceRecords[i] === 'leaveearly') && (attendanceRecords[i - 1] === 'late' || attendanceRecords[i - 1] === 'leaveearly'))) {continuousLateLeaveEarly = true;}}// 缺勤超过一次,或存在连续迟到/早退,则不符合条件if (absentCount > 1 || continuousLateLeaveEarly) {return false;}// 检查任意连续7次考勤的缺勤/迟到/早退次数for (let i = 0; i <= attendanceRecords.length - 7; i++) {let count = 0;for (let j = i; j < i + 7; j++) {if (attendanceRecords[j] !== 'present') {count++;}}if (count > 3) {return false;}}// 如果所有条件都符合,则员工能获得出勤奖return true;
}// 示例输入
let n = 2; // 表示考勤记录条数
let attendanceRecords1 = ['present', 'absent', 'late', 'present', 'present', 'leaveearly', 'present'];
let attendanceRecords2 = ['present', 'absent', 'absent', 'present', 'present', 'leaveearly', 'present'];// 输出结果
console.log(canGetAttendanceAward(attendanceRecords1)); // 应输出 true
console.log(canGetAttendanceAward(attendanceRecords2)); // 应输出 false

这段代码首先定义了一个 canGetAttendanceAward 函数,该函数接受一个考勤记录数组作为输入,并返回一个布尔值表示员工是否能获得出勤奖。函数内部,我们通过遍历考勤记录来统计缺勤次数,检查是否存在连续的迟到或早退,并使用滑动窗口方法检查任意连续7次考勤的情况,最终根据检查结果返回是否符合获奖条件。

求满足条件的最长子串的长度

给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子串,子串要求:
1、 只包含1个字母(a-z, A-Z),其余必须是数字;
2、 字母可以在子串中的任意位置;
如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。

解析

要找到满足上述条件的最长子串,我们可以遍历字符串,使用一个滑动窗口来检查每个可能的子串。对于每个窗口,我们需要确保它包含且仅包含一个字母和多个数字。我们可以通过记录字母的数量以及更新最长子串的长度来实现这一点。以下是具体步骤:

  1. 初始化两个指针startend来表示滑动窗口的起始和结束位置,初始化最长长度maxLength为-1,因为如果没有找到满足条件的子串,需要返回-1。
  2. 遍历字符串,移动end指针,对于每个新字符,检查它是字母还是数字。
  3. 如果当前窗口包含超过一个字母,移动start指针直到窗口再次满足条件(即包含且仅包含一个字母)。
  4. 在每个步骤中,如果当前窗口满足条件,更新maxLength
  5. 遍历完成后,返回maxLength

以下是实现这个算法的 JavaScript 代码:

function findLongestSubstrLength(s) {let maxLength = -1;let letterCount = 0; // 记录当前窗口中字母的数量let start = 0; // 滑动窗口的起始位置for (let end = 0; end < s.length; end++) {// 检查当前字符是否为字母if (isNaN(s[end])) {letterCount++;}// 如果字母数量超过1,移动start直到字母数量为1while (letterCount > 1) {if (isNaN(s[start])) {letterCount--;}start++;}// 如果当前窗口满足条件(包含且仅包含一个字母),更新maxLengthif (letterCount === 1) {maxLength = Math.max(maxLength, end - start + 1);}}return maxLength;
}// 示例
console.log(findLongestSubstrLength("a123")); // 输出: 4
console.log(findLongestSubstrLength("12345")); // 输出: -1
console.log(findLongestSubstrLength("abcd1234")); // 输出: -1
console.log(findLongestSubstrLength("1a2345")); // 输出: 6

这段代码中,isNaN函数用来检查一个字符是否为字母,因为isNaN会将参数转换为数字,如果转换失败(即参数是字母),则返回true。通过这种方式,我们可以区分字母和数字,进而统计每个滑动窗口中字母的数量,并更新满足条件的最长子串长度。

VLAN池

VLAN是一种对局域网设备进行逻辑划分的技术,为了标识不同的VLAN,引入VLAN ID(1-4094之间的整数)的概念。

定义一个VLAN ID的资源池(下称VLAN资源池),资源池中连续的VLAN用开始VLAN-结束VLAN表示,不连续的用单个整数表示,所有的VLAN用英文逗号连接起来。

现在有一个VLAN资源池,业务需要从资源池中申请一个VLAN,需要你输出从VLAN资源池中移除申请的VLAN后的资源池。

二、输入描述
第一行为字符串格式的VLAN资源池;
第二行为业务要申请的VLAN。

VLAN的取值范围为[1,4094]之间的整数。

三、输出描述
从输入VLAN资源池中移除申请的VLAN后字符串格式的VLAN资源池,输出要求满足题目描述中的格式,并且按照VLAN从小到大升序输出。

如果申请的VLAN不在原VLAN资源池内,输出原VLAN资源池升序排序后的字符串即可。

输入1 输入2 输出 说明
1-5 2 1,3-5 原VLAN资源池中有VLAN 1、2、3、4、5,从资源池中移除2后,剩下VLAN 1、3、4、5,按照题目描述格式并升序后的结果为1,3-5。
20-21,15,18,30,5-10 15 5-10,18,20-21,30 原VLAN资源池中有VLAN 5、6、7、8、9、10、15、18、20、21、30,从资源池中移除15后,资源池中剩下的VLAN为 5、6、7、8、9、10、18、20、21、30,按照题目描述格式并升序后的结果为5-10,18,20-21,30。
5,1-3 10 1-3,5 原VLAN资源池中有VLAN 1、2、3,5,申请的VLAN 10不在原资源池中,将原资源池按照题目描述格式并按升序排序后输出的结果为1-3,5。

解析

为了处理这个问题,我们可以按照以下步骤实现JavaScript代码:

  1. 解析输入的VLAN资源池字符串,将其转换为一个有序的VLAN ID列表。
  2. 检查要申请的VLAN是否在列表中,如果在,就从列表中移除该VLAN。
  3. 将更新后的VLAN列表转换回题目要求的格式。

下面是实现这个逻辑的JavaScript代码示例:

function updateVLANPool(pool, vlan) {// 将输入的VLAN资源池字符串转换为一个VLAN ID的数组let vlanArray = [];pool.split(',').forEach(part => {if (part.includes('-')) {let [start, end] = part.split('-').map(Number);for (let i = start; i <= end; i++) {vlanArray.push(i);}} else {vlanArray.push(Number(part));}});// 移除申请的VLANconst vlanIndex = vlanArray.indexOf(Number(vlan));if (vlanIndex !== -1) {vlanArray.splice(vlanIndex, 1);}// 将VLAN ID的数组转换回题目要求的格式vlanArray.sort((a, b) => a - b);let result = [];let start = vlanArray[0], end = vlanArray[0];for (let i = 1; i <= vlanArray.length; i++) {if (vlanArray[i] === vlanArray[i - 1] + 1) {end = vlanArray[i];} else {if (start === end) {result.push(`${start}`);} else {result.push(`${start}-${end}`);}start = end = vlanArray[i];}}return result.join(',');
}// 示例输入输出
console.log(updateVLANPool("1-5", "2")); // 输出: "1,3-5"
console.log(updateVLANPool("20-21,15,18,30,5-10", "15")); // 输出: "5-10,18,20-21,30"
console.log(updateVLANPool("5,1-3", "10")); // 输出: "1-3,5"

这个解决方案首先将VLAN资源池字符串转换成一个有序的数组,然后根据需求移除特定的VLAN,最后再将更新后的数组转换回题目要求的字符串格式。

晚会的小礼品发放

又到了一年的末尾,项目组让小明负责新年晚会的小礼品发放工作。

为使得参加晚会的同时所获得的小礼品价值相对平衡,需要把小礼品根据价格进行分组,但每组最多只能包括两件小礼品,并且每个分组的价格总和不能超过一个价格上限。

为了保证发放小礼品的效率,小明需要找到分组数目最少的方案。

你的任务是写一个程序,找出分组数最少的分组方案,并输出最少的分组数目。

二、输入描述
第一行数据为分组礼品价格之和的上限

第二行数据为每个小礼品的价格,按照空格隔开,每个礼品价格不超过分组价格和的上限。

10
5 5 10 2 7

解析

要解决这个问题,我们可以使用贪心算法的思想。首先,我们需要对小礼品的价格进行排序,然后从最小和最大的两端开始,尝试将它们分为一组。如果两个礼品的价格和小于等于给定的上限,我们就可以将它们分为一组,然后继续处理剩下的礼品。如果两个礼品的价格和大于给定的上限,那么我们就只能选择价格较大的礼品单独成组,然后继续处理剩下的礼品。这样,直到所有的礼品都被分组为止。

下面是这个算法的JavaScript实现:

function minGroups(limit, prices) {// 将礼品价格进行排序prices.sort((a, b) => a - b);let i = 0, j = prices.length - 1;let groups = 0;while (i <= j) {// 如果最小和最大的礼品价格之和小于等于限制,则这两个可以一组if (prices[i] + prices[j] <= limit) {i++; // 移动到下一个最小价格}j--; // 移动到下一个最大价格groups++; // 不管是否组合,这次操作至少增加了一个分组}return groups;
}// 示例
const limit = 10;
const prices = [5, 5, 10, 2, 7];
console.log(minGroups(limit, prices)); // 输出最少的分组数目

这段代码首先定义了一个minGroups函数,接受分组上限和礼品价格数组作为输入。通过排序、双指针技术,有效地将礼品分组,以确保总的分组数量最小。最后,通过调用这个函数并传入示例数据,可以得到最少的分组数量。

字符串中最长的非严格递增连续数字序列的长度

输入一个字符串仅包含大小写字母和数字,求字符串中包含的最长的非严格递增连续数字序列的长度,比如122889属于非严格递增连续数字序列。

二、输入描述
输入一个字符串仅包含大小写字母和数字,输入的字符串最大不超过255个字符。

三、输出描述
最长的非严格递增连续数字序列的长度。

解析

为了找出字符串中最长的非严格递增连续数字序列的长度,我们可以遵循以下步骤:

  1. 遍历字符串,检查每个字符是否为数字。
  2. 如果当前字符是数字,检查它是否形成了一个非严格递增的序列(即当前数字大于等于前一个数字)。
  3. 记录非严格递增连续数字序列的长度,并更新最长序列长度。

下面是这个算法的实现过程:

function longestNonStrictlyIncreasingSequenceLength(str) {let maxLength = 0; // 存储最长序列的长度let currentLength = 0; // 当前非严格递增序列的长度let prevDigit = -1; // 存储前一个数字字符,初始值设为-1表示没有前一个数字for (let i = 0; i < str.length; i++) {const char = str[i];// 检查当前字符是否为数字if (char >= '0' && char <= '9') {const digit = parseInt(char);// 如果当前数字大于等于前一个数字,则为非严格递增序列的一部分if (digit >= prevDigit) {currentLength++; // 增加当前序列的长度maxLength = Math.max(maxLength, currentLength); // 更新最长序列的长度} else {// 如果当前数字小于前一个数字,重置当前序列的长度为1currentLength = 1;}prevDigit = digit; // 更新前一个数字} else {// 如果当前字符不是数字,重置当前序列的长度和前一个数字currentLength = 0;prevDigit = -1;}}return maxLength;
}// 示例
const input = "a1b2c122889X99Y5z";
console.log(longestNonStrictlyIncreasingSequenceLength(input)); // 输出最长的非严格递增连续数字序列的长度

这段代码首先定义了一个longestNonStrictlyIncreasingSequenceLength函数,接受一个字符串作为输入。它遍历字符串中的每个字符,使用prevDigit变量来记录前一个数字字符,以便比较当前数字是否形成了非严格递增序列。通过更新currentLengthmaxLength,该函数能够计算并返回最长的非严格递增连续数字序列的长度。

太阳能板最大面积

给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。

但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。

现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为1个单位长度,计算如何选择两根支柱可以使太阳能板的面积最大。

解析

要计算能够获得最大太阳能板面积的两根支柱,我们可以使用一种称为"双指针"的技术。基本思路是从数组的两端开始,用两个指针表示可能的支柱,然后根据支柱的高度和宽度(指针之间的距离)计算面积。我们每次保留较高的支柱,并移动较短的支柱指针,直到两个指针相遇为止。这种方法能够确保我们检查了所有可能的支柱对,从而找到能够产生最大面积的支柱对。

下面是这个算法的JavaScript实现:

function maxArea(height) {let maxArea = 0; // 初始化最大面积为0let left = 0; // 左指针从数组的开始位置let right = height.length - 1; // 右指针从数组的结束位置while (left < right) {// 计算当前两根支柱形成的面积const currentArea = (right - left) * Math.min(height[left], height[right]);// 更新最大面积maxArea = Math.max(maxArea, currentArea);// 移动较短的支柱指针if (height[left] < height[right]) {left++;} else {right--;}}return maxArea; // 返回计算得到的最大面积
}

这段代码首先定义了一个名为maxArea的函数,它接受一个名为height的数组作为输入,该数组中的每个元素表示支柱的高度。函数内部,我们初始化了两个变量:maxArea用于追踪当前找到的最大面积,leftright分别作为两个指针的初始位置。然后,我们使用一个while循环,在左指针小于右指针的条件下进行迭代。在每次迭代中,我们计算当前指针对定义的面积,并根据这个面积更新maxArea。通过比较两个指针指向的支柱的高度,我们决定是移动左指针还是右指针,以期找到一个更大的面积。当左指针和右指针相遇时,循环结束,我们返回找到的最大面积。

内存地址分配

请实现一个简易内存池,根据请求命令完成内存分配和释放。

内存池支持两种操作命令,REQUEST和RELEASE,其格式为:

1、REQUEST

请求的内存大小表示请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出error。

2、RELEASE

释放的内存首地址 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址则输出error。

注意:

1.内存池总大小为100字节。
2.内存池地址分配必须是连续内存,并优先从低地址分配。
3.内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。
4.不会释放已申请的内存块的中间地址。
5.释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。

解析

class MemoryPool {constructor(size) {this.totalSize = size;this.memory = new Array(size).fill(0);this.allocations = new Map();}request(size) {if (size === 0 || size > this.totalSize) {console.log("error");return;}let startIndex = -1;for (let i = 0; i <= this.totalSize - size; i++) {if (this.memory.slice(i, i + size).every(val => val === 0)) {startIndex = i;break;}}if (startIndex !== -1) {this.memory.fill(1, startIndex, startIndex + size);this.allocations.set(startIndex, size);console.log(`Allocated memory at address ${startIndex}`);return startIndex;} else {console.log("error");}}release(address) {if (!this.allocations.has(address)) {console.log("error");return;}const size = this.allocations.get(address);this.memory.fill(0, address, address + size);this.allocations.delete(address);}
}// 测试
const memoryPool = new MemoryPool(100);
const addr1 = memoryPool.request(20); // 分配20字节内存
const addr2 = memoryPool.request(30); // 分配30字节内存
const addr3 = memoryPool.request(50); // 分配50字节内存
const addr4 = memoryPool.request(10); // 分配10字节内存,会输出error,内存不足memoryPool.release(addr2); // 释放30字节内存const addr5 = memoryPool.request(40); // 分配40字节内存,成功复用释放的内存memoryPool.release(addr2); // 输出error,该地址已经被释放过

这个实现创建了一个大小为100字节的内存池。request方法用于分配内存,release方法用于释放内存。内存分配是从低地址开始的,只有当请求的内存大小小于等于内存池的剩余空间时,分配才会成功。

路灯照明范围

在一条笔直的公路上安装了N个路灯,从位置0开始安装,路灯之间间距固定为100米。

每个路灯都有自己的照明半径,请计算第一个路灯和最后一个路灯之间,无法照明的区间的长度和。

二、输入描述
第一行为一个数N,表示路灯个数,1<=N<=100000。

第二行为N个空格分隔的数,表示路径的照明半径,1<=照明半径<=100000*100。

三、输出描述
第一个路灯和最后一个路灯之间,无法照明的区间的长度和。

解析

function calculateUnlitDistance(N, radii) {let arr = new Array((N - 1) * 100).fill(0);for (let index = 0; index < radii.length; index++) {const range = radii[index];let start =  index * 100 - rangelet end = index * 100 + rangeif(start<0){start = 0}arr = arr.fill(1, start, end);}return arr.filter(item=>item===0).length;
}// 示例输入
const N = 3;
const radii = [20, 70, 30];// 计算无法照明的区间长度
const unilluminatedDistance = calculateUnlitDistance(N, radii);
console.log(unilluminatedDistance);

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

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

相关文章

选择适合你的编程语言

引言 在当今瞬息万变的技术领域中&#xff0c;选择一门合适的编程语言对于个人职业发展和技术成长至关重要。每种语言都拥有独特的设计哲学、应用场景和市场需求&#xff0c;因此&#xff0c;在决定投入时间和精力去学习哪种编程语言时&#xff0c;我们需要综合分析多个因素&a…

力扣热题100_普通数组_56_合并区间

文章目录 题目链接解题思路解题代码 题目链接 56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区…

Nginx跳转模块之rewrite

一.location与rewrite模块的区别 rewrite&#xff1a;对访问的域名或者域名内的URL路径地址重写 location&#xff1a;对访问的路径做访问控制或者代理转发 二.rewrite模块基本内容 1.功能 通过正则表达式的匹配来改变URI&#xff0c;可以同时存在一个或多个指令&#xff0c…

第九节HarmonyOS 常用基础组件26-Radio

1、描述 单选框&#xff0c;提供相应的用户交互选择项。 2、接口 Radio(options:{value:string, group:string}) 3、参数 参数名 参数类型 必填 描述 value string 是 当前单选框的值。 group string 是 当前单选框的所属组名称&#xff0c;相同group的Radio只能…

AI误导游戏——LLM的危险幻觉

在当今科技高速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为日常生活和工作中不可或缺的一部分。特别是大语言模型&#xff08;LLM&#xff09;如GPT-4等&#xff0c;它们的智能表现令人惊叹&#xff0c;广泛应用于文本生成、语言翻译、情感分析等多个领域…

重大更新:GPT-4 API 现全面向公众开放!

重大更新&#xff1a;GPT-4 API 现全面向公众开放&#xff01; 在 AIGC&#xff08;人工智能生成内容&#xff09;领域内&#xff0c;我们一直致力于跟踪和分析如 OpenAI、百度文心一言等大型语言模型&#xff08;LLM&#xff09;的进展及其在实际应用中的落地情况。我们还专注…

变更ip后怎么查现在的代理ip地址?代理IP在网络请求中有哪些优势?

要查看当前的代理IP地址&#xff0c;可以尝试以下方法 浏览器设置&#xff1a;在大部分浏览器中&#xff0c;可以通过菜单选项中的“设置”或“帮助”来查找关于代理服务器的设置。在这里&#xff0c;可以看到当前使用的代理服务器地址、端口号以及是否启用了代理服务。在线工具…

浅谈密码学

文章目录 每日一句正能量前言什么是密码学对称加密简述加密语法Kerckhoffs原则常用的加密算法现代密码学的原则威胁模型&#xff08;按强度增加的顺序&#xff09; 密码学的应用领域后记 每日一句正能量 人生在世&#xff0c;谁也不能做到让任何人都喜欢&#xff0c;所以没必要…

什么是跨模态

跨模态&#xff08;Cross-modality&#xff09;是一个多学科领域中的术语&#xff0c;指的是涉及或整合了多种不同类型的信息模态或感官通道的过程或系统。在机器学习和人工智能领域&#xff0c;这通常涉及到整合视觉&#xff08;图像或视频&#xff09;、听觉&#xff08;声音…

数据结构——链表OJ题

目录 1.给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 2.给定一个带有头结点 head 的非空单链表&#xff0c;返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点…

LeetCode 102. 二叉树的层序遍历

题目链接https://leetcode.cn/problems/binary-tree-level-order-traversal/description/ 通过队列实现层序遍历 class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res new ArrayList<>();Queue<…

【实战篇】Redis单线程架构的优势与不足

前言 01 Redis中的多线程02 I/O多线程03 Redis中的多进程问题 04 结论 很多人都遇到过这么一道面试题&#xff1a;Redis是单线程还是多线程&#xff1f;这个问题既简单又复杂。说他简单是因为大多数人都知道Redis是单线程&#xff0c;说复杂是因为这个答案其实并不准确。 难道R…

Redis做缓存的几种模式以及缓存雪崩、缓存击穿、缓存穿透分别是什么,怎么解决

怎么做 缓存可以建立在客户端也可以建立在服务端&#xff08;注意这里是广义的客户端、服务端&#xff0c;服务A向服务B发请求&#xff0c;那么A就是客户端&#xff09; 理论上来将每个服务端都应该给自己建立缓存&#xff0c;因为微服务要有一定的互不信任原则&#xff08;请…

易宝OA DownloadFile 任意文件读取漏洞复现

0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA系统DownloadFile接口处存在任意文件读取漏洞,未授权的攻击者可以利用此漏洞…

java集合--List集合的基本用法

一、ArrayList集合 1.ArrayList集合的特点 2.ArrayList集合的一些方法 ①.add(Object element) 向列表的尾部添加指定的元素。 ②.size() 返回列表中的元素个数。 ③.get(int index) 返回列表中指定位置的元素&#xff0c;index从0开始。 public class Test {public static …

【Docker】构建pytest-playwright镜像并验证

Dockerfile FROM ubuntu LABEL maintainer "langhuang521l63.com" ENV TZAsia/Shanghai #设置时区 #安装python3依赖与下载安装包 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \&& apt update \&&…

大模型+影像:智能手机“上春山”

这个春节假期&#xff0c;一首《上春山》火了。吃瓜群众热热闹闹学了一个假期的“春山学”&#xff0c;了解了抢占C位的各种技巧。 假期过去&#xff0c;开工大吉&#xff0c;手机行业开始抢占今年的C位。那么问题来了&#xff0c;今年智能手机最大的机会点在哪里&#xff1f;答…

C++ string常见用法 + 练手习题

部分内容摘抄自http://t.csdnimg.cn/BM0jO 目录 温故&#xff1a;C库函数中和字符串有联系的函数知新&#xff1a;C string常见用法string的初始化 1.常见初始化方式string对象的操作 1.用cin获取键盘输入的值 2.用getline读取一整行 3.string对…

布隆过滤器笔记

课程地址 布隆过滤器由一个很长的二进制向量和一系列哈希函数组成 特性&#xff1a;布隆过滤器可以告诉我们 “某样东西一定不存在或者可能存在”&#xff0c;也就是说布隆过滤器说这个数不存在则一定不存在&#xff0c;布隆过滤器说这个数存在可能不存在。这个特性能很好地被…

如何避免软件测试的遗漏或重复?

在实际软件测试中&#xff0c;经常遇到遗漏测试点&#xff0c;测试不充分&#xff1b;或者重复测试&#xff0c;造成资源浪费的情况。因此如何避免软件测试遗漏或重复&#xff0c;非常重要。 1、实施过程 首先&#xff0c;通过梳理某个领域的相关项目&#xff0c;分析相关业务规…