【周赛总结】巧用双指针降低时间复杂度

水平不高,就只说周赛的前两题。

第一题

题目

给你一个字符串数组 words 和一个字符 separator ,请你按 separator 拆分 words 中的每个字符串。返回一个由拆分后的新字符串组成的字符串数组,不包括空字符串 。separator 用于决定拆分发生的位置,但它不包含在结果字符串中。拆分可能形成两个以上的字符串。结果字符串必须保持初始相同的先后顺序。

示例:

输入:words = ["one.two.three","four.five","six"], separator = "."
输出:["one","two","three","four","five","six"]
解释:在本示例中,我们进行下述拆分:

"one.two.three" 拆分为 "one", "two", "three"
"four.five" 拆分为 "four", "five"
"six" 拆分为 "six" 

因此,结果数组为 ["one","two","three","four","five","six"] 。

解释:在本示例中,"|||" 的拆分结果将只包含一些空字符串,所以我们返回一个空数组 [] 。 
1 <= words.length <= 100
1 <= words[i].length <= 20
words[i] 中的字符要么是小写英文字母,要么就是字符串 ".,|$#@" 中的字符(不包括引号)
separator 是字符串 ".,|$#@" 中的某个字符(不包括引号)

思路&Code

就是很简单的利用基本函数

class Solution:
    def splitWordsBySeparator(self, words: List[str], separator: str) -> List[str]: 
        result = []
        for word in words:
            split_words = word.split(separator)
            result.extend([x for x in split_words if x != ''])
        return result

第二题

题目

给你一个下标从 0 开始、由正整数组成的数组 nums 。你可以在数组上执行下述操作 任意 次:选中一个同时满足 0 <= i < nums.length - 1 和 nums[i] <= nums[i + 1] 的整数 i 。将元素 nums[i + 1] 替换为 nums[i] + nums[i + 1] ,并从数组中删除元素 nums[i] 。
返回你可以从最终数组中获得的 最大 元素的值。

示例 1:

输入:nums = [2,3,7,9,3]
输出:21
解释:我们可以在数组上执行下述操作:
- 选中 i = 0 ,得到数组 nums = [5,7,9,3] 。
- 选中 i = 1 ,得到数组 nums = [5,16,3] 。
- 选中 i = 0 ,得到数组 nums = [21,3] 。
最终数组中的最大元素是 21 。可以证明我们无法获得更大的元素。
示例 2:

输入:nums = [5,3,3]
输出:11
解释:我们可以在数组上执行下述操作:
- 选中 i = 1 ,得到数组 nums = [5,6] 。
- 选中 i = 0 ,得到数组 nums = [11] 。
最终数组中只有一个元素,即 11 。

思路&Code

略看题目,看到最大,脑海里就闪过贪心的想法,但是细读题目,可以看到题目在进行操作时要求比较大小,因此不能使用排序破环当前的大小顺序。但是我们发现正向遍历可能导致错误地相加导致失去最大的操作路径,为了避免这种情况地发生,我们选择反向遍历,然后操作的条件照抄就行(小于等于改为大于等于),于是得到以下代码:

class Solution:
    def maxArrayValue(self, nums: List[int]) -> int:
        n=len(nums)
        nums.reverse()
        lt,mt,rt=0,1,n-1
        while mt<=rt:
            if nums[lt]>=nums[mt]:
                nums[lt]=nums[lt]+nums[mt]
                nums.pop(mt)
                rt-=1
            else:
                mt+=1
                lt+=1
        return max(nums)

这一版代码的思想非常简单,就是利用双指针lt与mt来确定两个相互比较的元素,如果两个元素不满足相加条件,即都前进(lt,mt各自+1),若两数满足相加条件,那么mt前进一格,lt则不变,因为是下一个数与前两数和比较,即mt+1,lt不变(此时lt处的元素是两数和),利用pop方法删除Mt代表的元素,同时记录数组长度、控制while循环结束的rt-1。

但是问题是pop方法的运用增加了时间复杂度,导致超时,那该怎么办呢?

想到了双指针,没必要删除那个元素,只需要控制好双指针的前进把被“删除”了的元素略过就行了啊,而且这样一来数组的长度也不会有变化了,原先设置的随时变化的rt也可以删除了,while的结束条件直接控制在n-1就可以了。

class Solution:
    def maxArrayValue(self, nums: List[int]) -> int:
        n=len(nums)
        nums.reverse()
        lt,rt=0,1
        while rt<=n-1:
            if nums[lt]>=nums[rt]:
                nums[rt]=nums[lt]+nums[rt]
            rt+=1
            lt+=1
        return max(nums)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值