Leecode刷题C语言之或值至少K的最短子数组①

执行结果:通过

执行用时和内存消耗如下:

复制代码
int minimumSubarrayLength(int* nums, int numsSize, int k) {
    int left = 0;
    int right = 0;
    int currentOr = 0;
    int minLength = INT_MAX;

    while (right < numsSize) {
        // 扩展窗口,添加新元素到 currentOr
        currentOr |= nums[right];

        // 当 currentOr >= k 时,尝试收缩窗口
        while (currentOr >= k && left <= right) {
            // 更新最短长度
            if (right - left + 1 < minLength) {
                minLength = right - left + 1;
            }
            // 移除左端点元素,并更新 currentOr
            int tempOr = 0;
            for (int i = left + 1; i <= right; ++i) {
                tempOr |= nums[i];
            }
            currentOr = tempOr;
            ++left;
        }

        ++right;
    }

    // 检查是否有符合条件的子数组
    return minLength == INT_MAX ? -1 : minLength;
}

解题思路:

这段代码的解题思路旨在寻找一个最短的连续子数组,使得该子数组中所有数字的按位或(bitwise OR)结果大于等于给定的整数 k。以下是详细的解题步骤:

  1. 初始化变量
    • leftright 分别表示当前考虑的子数组的左右边界,初始都设为 0。
    • currentOr 用于存储当前子数组内所有元素的按位或结果,初始化为 0。
    • minLength 用于记录符合条件的最短子数组的长度,初始化为 INT_MAX(一个非常大的数,表示初始时未找到符合条件的子数组)。
  2. 遍历数组
    • 使用一个 while 循环遍历数组,条件是 right < numsSize,即右边界未超出数组长度。
  3. 扩展窗口
    • 在每次循环中,首先通过 currentOr |= nums[right] 将当前元素加入到 currentOr 中,扩展窗口的右边界。
  4. 尝试收缩窗口
    • 检查 currentOr 是否大于等于 k。如果是,说明当前窗口(或更大的窗口)可能包含符合条件的子数组。
    • 进入一个内层 while 循环,条件是 currentOr >= kleft <= right。这个循环尝试收缩窗口的左边界,以找到最短的可能子数组。
  5. 更新最短长度
    • 在内层循环中,如果当前窗口的长度(right - left + 1)小于 minLength,则更新 minLength
  6. 收缩窗口并更新 currentOr
    • 为了收缩窗口,需要从当前窗口中移除左边界的元素。代码中的实现方式是通过一个循环从 left + 1right 重新计算 currentOr(这里有一个效率问题,下面会提到)。
    • 更新 currentOr 为不包含左边界元素的新值。
    • left 右移一位,继续尝试收缩窗口。
  7. 继续扩展窗口
    • 完成内层循环后,继续扩展外层循环的右边界,即将 right 右移一位。
  8. 返回结果
    • 循环结束后,检查 minLength 是否仍为 INT_MAX。如果是,说明没有找到符合条件的子数组,返回 -1
    • 否则,返回 minLength,即符合条件的最短子数组的长度。

效率问题

  • 在收缩窗口的过程中,代码通过一个循环重新计算 currentOr,这实际上是不必要的。可以通过记录移除元素之前的 currentOr 值和移除元素本身,然后使用按位运算直接更新 currentOr,从而提高效率。

优化思路

  • 可以使用一个变量来跟踪上一次计算 currentOr 时左边界元素对 currentOr 的贡献,这样在移除左边界元素时,可以直接通过按位运算减去该贡献,而无需重新计算整个窗口的 currentOr
相关推荐
iAkuya9 分钟前
(leetcode)力扣100 62N皇后问题 (普通回溯(使用set存储),位运算回溯)
算法·leetcode·职场和发展
近津薪荼9 分钟前
dfs专题5——(二叉搜索树中第 K 小的元素)
c++·学习·算法·深度优先
xiaoye-duck11 分钟前
吃透 C++ STL list:从基础使用到特性对比,解锁链表容器高效用法
c++·算法·stl
松☆14 分钟前
CANN与大模型推理:在边缘端高效运行7B参数语言模型的实践指南
人工智能·算法·语言模型
_F_y16 分钟前
C++重点知识总结
java·jvm·c++
打工的小王17 分钟前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
毕设源码-赖学姐18 分钟前
【开题答辩全过程】以 高校体育场馆管理系统为例,包含答辩的问题和答案
java·spring boot
我真会写代码20 分钟前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
vx_Biye_Design20 分钟前
【关注可免费领取源码】房屋出租系统的设计与实现--毕设附源码40805
java·spring boot·spring·spring cloud·servlet·eclipse·课程设计
java干货25 分钟前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法