求字符串中所有整数的最小和
输入字符串 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*N
和 2*N+1
,符合题目的要求。此代码在遇到叶子节点时检查其值是否为当前已知的最小值,并在是的情况下更新路径。这确保了最终的路径是到达值最小的叶子节点的路径。
数组去重和排序
给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。
解析
针对这个问题,我们可以使用JavaScript来解决。以下是一个分步解决方案:
- 统计元素出现的次数:遍历数组,使用一个对象(或Map)来统计每个元素出现的次数。
- 删除重复元素:这一步在统计的同时已经完成,因为对象(或Map)的键是唯一的。
- 根据出现次数和首次出现顺序排序:首先根据出现次数对元素进行排序,如果两个元素出现次数相同,则根据它们首次出现的顺序来排序,这需要我们在统计时额外记录每个元素首次出现的索引。
下面是实现这个算法的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);
}
这个算法的核心是滑动窗口技术。它从数组的左端开始,用两个指针(start
和 end
)表示当前考虑的子数组的边界。随着算法的进行,end
指针向右移动以增加子数组的和,当子数组的和超过目标和时,start
指针向右移动以减少子数组的和。当找到一个和等于目标和的子数组时,检查其长度是否是目前发现的最长的,并相应地更新最长子数组的信息。
请注意,此算法假设数组中所有的数字都是正整数。这是因为,如果数组中包含负数或零,当前和可能在不增加子数组长度的情况下减少,这会使问题变得更加复杂。
员工出勤信息
为了解决这个问题,我们可以编写一个 JavaScript 函数来处理考勤信息并根据给定条件判断员工是否符合获得出勤奖的资格。算法的实现步骤大致如下:
- 遍历考勤记录数组,统计缺勤次数,并检查是否存在连续的迟到/早退。
- 使用一个滑动窗口(大小为7)遍历考勤记录数组,检查任意连续7次考勤中,缺勤/迟到/早退的次数是否超过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。
解析
要找到满足上述条件的最长子串,我们可以遍历字符串,使用一个滑动窗口来检查每个可能的子串。对于每个窗口,我们需要确保它包含且仅包含一个字母和多个数字。我们可以通过记录字母的数量以及更新最长子串的长度来实现这一点。以下是具体步骤:
- 初始化两个指针
start
和end
来表示滑动窗口的起始和结束位置,初始化最长长度maxLength
为-1,因为如果没有找到满足条件的子串,需要返回-1。 - 遍历字符串,移动
end
指针,对于每个新字符,检查它是字母还是数字。 - 如果当前窗口包含超过一个字母,移动
start
指针直到窗口再次满足条件(即包含且仅包含一个字母)。 - 在每个步骤中,如果当前窗口满足条件,更新
maxLength
。 - 遍历完成后,返回
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代码:
- 解析输入的VLAN资源池字符串,将其转换为一个有序的VLAN ID列表。
- 检查要申请的VLAN是否在列表中,如果在,就从列表中移除该VLAN。
- 将更新后的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个字符。
三、输出描述
最长的非严格递增连续数字序列的长度。
解析
为了找出字符串中最长的非严格递增连续数字序列的长度,我们可以遵循以下步骤:
- 遍历字符串,检查每个字符是否为数字。
- 如果当前字符是数字,检查它是否形成了一个非严格递增的序列(即当前数字大于等于前一个数字)。
- 记录非严格递增连续数字序列的长度,并更新最长序列长度。
下面是这个算法的实现过程:
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
变量来记录前一个数字字符,以便比较当前数字是否形成了非严格递增序列。通过更新currentLength
和maxLength
,该函数能够计算并返回最长的非严格递增连续数字序列的长度。
太阳能板最大面积
给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。
但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。
现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为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
用于追踪当前找到的最大面积,left
和right
分别作为两个指针的初始位置。然后,我们使用一个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);