【LeetCode】1403. 非递增顺序的最小子序列

image.png

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 1 <= nums.length <= 500
    • 1 <= nums[i] <= 100

二、思路分析:

我们读取本题内容,题目要求在一组数组中找出最小的子序列,其子序列的和要大于数组中剩余的元素和。基本明白题目要求,但是仍然存在一些疑问,我们继续审题:

  • 如果存在对个最小的子序列,则返回长度最小且元素之和最大的子序列
  • 子序列的位置可以移动,不要求子序列的元素在原数组中的连续性
  • 返回的子序列的是按递减顺序排序的

根据题目的要求,因此解答本题我们可以使用模拟方法进行解答即可,以下思路如下:

  • 因为需要返回元素和最大且长度最小的子序列,我们可以将nums数组按递减的顺序排序处理nums.sort(reverse=True)
  • 在nums数组从第一个位置推出元素,当ans临时数组的和大于nums的元素和时,则退出循环,返回ans结果
  • 当ans临时数组元素和小于nums元素和时,则nums.pop(0)推出第一个元素num,ans将num元素添加 根据上述思路,我们可以快速使用Python实现,代码如下:
    class Solution(object):
        def minSubsequence(self, nums):
            """
            :type nums: List[int]
            :rtype: List[int]
            """
            nums.sort(reverse=True)
            ans = []
            while nums:
                if sum(ans) > sum(nums):
                    break
                else:
                    num = nums.pop(0)
                    ans.append(num)
            return ans
    复制代码

根据上述实现过程,发现并不是最优雅的写法,我们可以继续优化,使用列表分段的方法减少内存和时间的消耗

  • 同理我们仍然要先将nums数组进行递减排序处理
  • 计算出nums所有元素和total,并定义一个tmp存储nums子序列的和
  • 使用for循环遍历nums列表,每取一个元素tmp进行累计子序和
  • 当tmp子序和大于total-tmp时,则返回结果nums[:i+1]
    class Solution(object):
        def minSubsequence(self, nums):
            """
            :type nums: List[int]
            :rtype: List[int]
            """
            nums.sort(reverse=True)
            total,tmp = sum(nums),0       
            for i,num in enumerate(nums):
                tmp += num
                if tmp > total-tmp:
                     return nums[:i+1]
    复制代码

三、总结:

本题考察我们对数组元素遍历,进行计算子序和并进行判断,在循环过程中,避免重复耗时大的计算过程将sum函数替换成tmp变量累计和计算,进一步提高我们代码的时间耗时。AC提交记录如下: image.png

  • 时间复杂度:O(nlogn),n为数组nums的长度
  • 空间复杂度:O(logn),n为数组nums的长度

以上是本期内容,欢迎大佬们点赞评论,下期见~~~

猜你喜欢

转载自juejin.im/post/7129727151191900167
今日推荐