5.1 LeetCode 热题 100 (普通数组)

最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

首次提交

想法

贪心:在遍历数组时,累加当前元素。如果当前累加和变成负数,则丢弃累加的结果,从下一个元素重新开始累加。在每一步都记录当前的最大和。

实现流程

  1. 初始化:
    • 使用一个变量 max_sum 保存全局最大和,初始化为数组的第一个元素。
    • 使用另一个变量 current_sum 保存当前子数组的累加和,初始化为 0。
  2. 遍历数组:
    • 将当前元素加入 current_sum
    • 如果 current_sum 大于 max_sum,更新 max_sum
    • 如果 current_sum 小于 0,重新将 current_sum 置为 0(因为负数对后续的累加没有贡献)。
  3. 返回 max_sum

代码:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        max_sum = nums[0]  # 全局最大和
        current_sum = 0  # 当前子数组的累加和

        for num in nums:
            current_sum += num
            max_sum = max(max_sum, current_sum)
            if current_sum < 0:
                current_sum = 0

        return max_sum
Python

时间复杂度

$O(n)$,只需遍历数组一次。

空间复杂度

$O(1)$,只使用了常数级额外空间。


合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

首次尝试

想法

使用双指针 leftright,其中 left 用于遍历,right 用于找到和当前区间 intervals[left] 重叠的区间。如果发现两个区间有重叠(即 temp[1] >= intervals[right][0]),则将 temp 更新为合并后的区间,并继续移动 right。将合并结果存入 result 中。

问题代码

class Solution:
    def merge(self, intervals):
        result = []
        right = 1
        for left in range(len(intervals)-1):
            if left < right - 1:
                continue
            temp = [intervals[left][0], intervals[left][1]]
            while temp[1] >= intervals[right][0]:
                temp = [temp[0], intervals[right][1]]
                right += 1
            right += 1
            result.append(temp)
        return result

intervals = [[1,3],[2,6],[8,10],[15,18]]
# intervals = [[1,4],[4,5]]
solution = Solution()
print(solution.merge(intervals))
Python

问题

未排序问题: intervals 在逻辑处理前未进行排序。若输入区间未按 start 排序,程序无法正确处理。

数组越界:while temp[1] >= intervals[right][0] 中,right 的索引可能越界,导致运行时错误。

逻辑不清晰:

  • if left < right - 1: continue 这部分可能会跳过 left 索引的逻辑处理,导致某些区间被遗漏。
  • right 增加两次(while 和后续的 right += 1),这可能导致索引错乱。

复杂度

当前代码的复杂度接近 $O(n^2)$,因为每个区间可能通过 while 遍历多次,这会在处理较多区间时效率较低。


改进

  1. 排序: 先按区间的起点 startintervals 进行排序,以保证合并逻辑的正确性。
  2. 双指针逻辑: 通过一个单指针遍历 intervals,判断当前区间是否与上一个合并区间重叠。

代码

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        # 边界处理:如果输入列表为空或仅有一个区间
        if not intervals:
            return []
        # 通过lambda表达式对sorted按起点排序
        sorted_intervals = sorted(intervals, key = lambda x:x[0])
        result = []
        min_num = sorted_intervals[0][0]
        max_num = sorted_intervals[0][1] 
        for i in range(1,len(intervals)):
            # 有重叠
            if max_num >= sorted_intervals[i][0]:
                if max_num < sorted_intervals[i][1]:
                    max_num = sorted_intervals[i][1]
            else:
                result.append([min_num, max_num])
                min_num = sorted_intervals[i][0]
                max_num = sorted_intervals[i][1]
        result.append([min_num, max_num])
        return result
Python

合并逻辑

  • 如果当前区间的起点 sorted_intervals[i][0] 小于或等于前一个区间的终点 max_num,则尝试更新 max_num
  • 如果没有重叠,将前一个区间加入结果,并更新 min_nummax_num
  • 最后,将最后一个区间添加到结果中,确保不遗漏。

注意事项

  • lambda表达式排序
  • 当有重叠区域时,仍要判断max_num是否大于sorted_intervals[i][1], (例如[[1,5],[2,4]])
  • 注意最后一个索引时,假如有重叠则只更新了max_num没有加入result列表,假如没有重叠则将之前的[min_num, max_num] 加入result列表,没有加入之后更新的[min_num, max_num] ,因此需要在循环结束后再添加一个append().

时间复杂度

  • 排序部分: $O(n \log n)$
  • 遍历部分: $O(n)$
  • 总复杂度: $O(n \log n)$

最终优化

代码

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        if not intervals:
            return []

        # 按起点排序
        sorted_intervals = sorted(intervals, key=lambda x: x[0])

        result = []
        current_start, current_end = sorted_intervals[0]

        for i in range(1, len(sorted_intervals)):
            start, end = sorted_intervals[i]
            if start <= current_end:  # 有重叠
                current_end = max(current_end, end)
            else:  # 无重叠,保存当前区间
                result.append([current_start, current_end])
                current_start, current_end = start, end

        # 添加最后一个区间
        result.append([current_start, current_end])
        return result
Python

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇