持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目提示
2 <= nums.length <= 105
0 <= nums[i] <= 106
- 可以保证至少有一种方法能够按题目所描述的那样对
nums
进行划分。
二、思路分析:
我们今天拿到本题是 leetcode 难度为中等题 915. 分割数组。题目要求对nums数组进行划分为left和right两个数组,并且left数组中所有的元素要小于等于right中所有的元素,并返回left数组长度。根据提示需要明确几点信息:
- left数组中元素要小于等于right中元素
- left的数组长度要尽可能小
- left和right数组是非空的,且是连续的
根据题目内容介绍,我们可以使用遍历方法来模拟划分,思路如下:
-
方法一:两次遍历
- 因为题目要求划分的left数组元素要小于right数组元素且是连续的,因此不能对nums进行排序,需要使用循环来查找到right数组中最小值大于left数组的最大值的位置即可
- 首先定义一个min_right数组,倒序(从右往左)遍历nums数组(n-2,0,-1),每一个索引位置的最小值,存储在min_right数组中
- 初始化max_left值为nums[0],再使用for循环从左往右遍历nums数组(1,n),当max_left 小于等于min_right[i]时,返回索引i值
- 当max_left大于min_right[i]值时,则max_left从nums[i]与max_left之间最大值
class Solution(object): def partitionDisjoint(self, nums): """ :type nums: List[int] :rtype: int """ n = len(nums) min_right = [0]*n min_right[-1] = nums[-1] for i in range(n-2,0,-1): min_right[i] = min(min_right[i+1],nums[i]) max_left = nums[0] for i in range(1,n): if max_left <= min_right[i]: return i max_left = max(nums[i],max_left)
-
方法二:前缀最大值
- 在两次遍历过程中需要使用一个临时数组记录nums每一个元素的最小值,我们可以使用max_lef来记录left数组最大值,index来记录max_left大于nums[i]位置
- 初始化maxnum和max_left为nums[0],index指向0
- 从1开始遍历nums数组,当nums[i] 小于max_left,则index赋值为i,且max_left更新为maxnum值
- 当nums[i]值大于等于max_left,则maxnum值从max_left与nums[i]中选择最大值更新
- 直到遍历完nums数组,返回index+1
class Solution(object): def partitionDisjoint(self, nums): """ :type nums: List[int] :rtype: int """ n = len(nums) max_left = maxnum = nums[0] index = 0 for i in range(1,n): if nums[i] < max_lef: index = i max_lef = maxnum else: maxnum = max(max_left,nums[i]) return index+1
三、总结:
本题考察前缀和应用,需要定义max_left和index来记录left数组最大数与其索引位置,AC提交记录如下:
- 时间复杂度:O(n),n为nums数组长度
- 空间复杂度:O(1),没有使用额外数组
以上是本期内容,欢迎大佬们点赞评论,下期见~~~