news 2026/7/28 8:52:43

hot100刷题第5天(53,56,189,238)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
hot100刷题第5天(53,56,189,238)

53最大子数组和

是拼爹还是靠自己?这是一个问题...
从前面累加到现在是谓继承
从现在另起炉灶是谓靠自己

这个题目在我之前的文章中有详细分析过,这里可以用贪心来解决,不多介绍

int maxSubArray(vector<int>& nums) { int maxarrValue = INT32_MIN; int sum = 0; int index = 0; for(int i = index; i < nums.size(); i++){ sum += nums[i]; maxarrValue = max(maxarrValue, sum); if(sum < 0){ sum = 0; } } return maxarrValue; }



56 合并区间


#include<bits/stdc++.h> using namespace std; vector<vector<int>> merge(vector<vector<int>>& intervals) { if(intervals.size() <= 1){ return intervals; } sort(intervals.begin(), intervals.end()); vector<vector<int>> result; int resultLeft = intervals[0][0]; int resultRight = intervals[0][1]; for(int i=1; i<intervals.size(); i++){ if(intervals[i][0] <= resultRight){ resultRight = max(resultRight, intervals[i][1]); }else{ result.push_back({resultLeft, resultRight}); resultLeft = intervals[i][0]; resultRight = intervals[i][1]; } } result.push_back({resultLeft, resultRight}); return result; } int main(){ vector<vector<int>> intervals = {{1,3},{2,6},{8,10},{15,18}}; vector<vector<int>> result = merge(intervals); for(const auto& element1 : result){ for(const auto& element2 : element1){ cout << element2 << ' '; } cout << endl; } return 0; }

核心思路

  1. 排序:这是解决问题的关键第一步。我们需要将所有区间按照它们的起始点进行升序排序。如果两个区间的起始点相同,它们的相对顺序不重要。排序之后,所有潜在的重叠区间都会被“相邻”地排列在一起

  2. 初始化“工作区”:创建了一个名为result的空数组,用于存放最终合并后的区间。
    这里我们用resultLeft 和 resultRight 两个变量来存储和更新正在合并的当前区间。将它们初始化为排序后的第一个区间 intervals[0] 的起始和结束点。这两个变量就像一个临时的“工作台”,用来处理所有重叠的区间。

  3. 循环与合并:

  • 如果当前区间与“工作区”有重叠(intervals[i][0] <= resultRight):更新了“工作区”的右边界。你使用了 max(resultRight, intervals[i][1]),这确保了工作区的右边界总是包含所有重叠区间的最大值。

  • 如果当前区间与“工作区”没有重叠(else):

    • 这说明前面连续的重叠区间已经全部处理完毕。将“工作区”中的结果{resultLeft, resultRight}推入result数组。

    • 然后,将“工作区”重置,用当前的区间intervals[i]的起始点和结束点来作为新的工作区,准备处理下一组重叠区间。

两个区间 [a, b] 和 [c, d]重叠的条件是 c <= b

4.收尾工作:

  • 循环结束后,最后一个正在合并的区间还没有被推入 result 数组。这是因为它的“工作区”没有遇到下一个不重叠的区间来触发 else 分支。
  • 因此,需要在循环结束后,再将最后的“工作区” {resultLeft, resultRight} 推入 result 数组。这一步是确保所有区间都被处理的关键。

189 轮转数组

好的,我们来聊聊 LeetCode 189 题“轮转数组”(Rotate Array)。这道题有很多种解法,每种方法都有不同的优缺点。

1. 额外数组法

这是最直观的解法。创建一个新数组,然后将原数组的元素按照轮转后的位置放到新数组中。

  • 思路:

    • 创建一个和原数组大小一样的新数组new_nums

    • 遍历原数组nums,对于每个元素nums[i],计算它在新数组中的位置(i + k) % n,其中n是数组长度,k是轮转的步数。

    • nums[i]放到new_nums[(i + k) % n]

    • 最后,将新数组的元素复制回原数组。

  • 优点: 简单易懂,不易出错。

  • 缺点: 需要额外的 O(n) 空间。

#include <vector> #include <iostream> class Solution { public: void rotate(std::vector<int>& nums, int k) { int n = nums.size(); // 对 k 进行取模,防止 k 超过数组长度 k = k % n; // 创建一个临时数组 std::vector<int> temp(n); // 将轮转后的元素放入临时数组中 for (int i = 0; i < n; ++i) { temp[(i + k) % n] = nums[i]; } // 将临时数组的元素复制回原数组 nums = temp; } };

三次翻转法

这是最高效且优雅的解法,空间复杂度为 O(1),时间复杂度为 O(n)。它的核心思想是利用反转操作的特性。

  • 思路:

    1. 反转整个数组

    2. 反转前 k 个元素

    3. 反转后 n - k 个元素

  • 举例:

    • 数组nums = [1, 2, 3, 4, 5, 6, 7],k = 3

    • 1. 反转整个数组:[7, 6, 5, 4, 3, 2, 1]

    • 2. 反转前 k 个元素: 反转[7, 6, 5]得到[5, 6, 7]。数组变为[5, 6, 7, 4, 3, 2, 1]

    • 3. 反转后 n - k 个元素: 反转[4, 3, 2, 1]得到[1, 2, 3, 4]。数组变为[5, 6, 7, 1, 2, 3, 4]

    • 最终结果正确。

  • 优点: 算法简洁,易于实现,且效率最高。

#include <vector> #include <algorithm> // 包含 std::reverse class Solution { public: void rotate(std::vector<int>& nums, int k) { int n = nums.size(); // 对 k 进行取模,防止 k 超过数组长度 k = k % n; // 1. 反转整个数组 std::reverse(nums.begin(), nums.end()); // 2. 反转前 k 个元素 std::reverse(nums.begin(), nums.begin() + k); // 3. 反转后 n-k 个元素 std::reverse(nums.begin() + k, nums.end()); } };

238 除自身以外数组的乘积

这道题可以通过两次遍历来解决,核心思想是:对于数组中的每一个元素nums[i],它的结果应该是它左侧所有元素的乘积乘以右侧所有元素的乘积

  • 第一次遍历(计算左侧乘积)

    • 创建一个result向量,大小与输入数组nums相同。

    • 从左到右遍历nums,用一个变量left_product累积左侧的乘积。

    • result向量的对应位置存入left_product的值。

  • 第二次遍历(计算右侧乘积并更新结果)

    • 从右到左遍历nums,用一个变量right_product累积右侧的乘积。

    • result向量中对应位置的值乘以right_product

#include<bits/stdc++.h> using namespace std; vector<int> productExceptSelf(vector<int>& nums) { int length = nums.size(); vector<int> result(length); int leftMul = 1; for(int i=0; i<length; i++){ result[i] = leftMul; leftMul *= nums[i]; } int rightMul=1; for(int i=length-1; i>=0; i--){ result[i] *=rightMul; rightMul *= nums[i]; } return result; } int main(){ vector<int> nums = {1,2,3,4}; vector<int> result = productExceptSelf(nums); for(const auto& element : result){ cout << element << ' '; } return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 14:41:59

如何在presenterm中高效加载远程资源:图片与代码引用完整指南

如何在presenterm中高效加载远程资源&#xff1a;图片与代码引用完整指南 【免费下载链接】presenterm A terminal slideshow tool 项目地址: https://gitcode.com/GitHub_Trending/pr/presenterm presenterm是一款功能强大的终端幻灯片工具&#xff0c;它允许用户通过简…

作者头像 李华
网站建设 2026/7/14 14:42:01

如何快速掌握GitHub Flavored Markdown:从入门到精通的完整指南

如何快速掌握GitHub Flavored Markdown&#xff1a;从入门到精通的完整指南 【免费下载链接】README README文件语法解读&#xff0c;即Github Flavored Markdown语法介绍 项目地址: https://gitcode.com/gh_mirrors/re/README GitHub Flavored Markdown&#xff08;GFM…

作者头像 李华
网站建设 2026/7/14 14:42:12

Cobalt项目Docker部署:5个常见问题终极解决方案

Cobalt项目Docker部署&#xff1a;5个常见问题终极解决方案 【免费下载链接】cobalt save what you love 项目地址: https://gitcode.com/gh_mirrors/co/cobalt Cobalt是一个强大的媒体下载和处理工具&#xff0c;通过Docker部署可以让您快速搭建自己的媒体处理实例。在…

作者头像 李华
网站建设 2026/7/14 14:42:10

终极Emoji Mart数据压缩指南:5个减少传输大小的关键技术方案

终极Emoji Mart数据压缩指南&#xff1a;5个减少传输大小的关键技术方案 【免费下载链接】emoji-mart &#x1f3ea; One component to pick them all 项目地址: https://gitcode.com/gh_mirrors/em/emoji-mart Emoji Mart表情数据压缩是现代前端开发中提升应用性能的关…

作者头像 李华