Leetcode日练17 #1299 #283 Replace Elements with Greatest element on the Right side & Move Zeroes

本文探讨了两种数组操作的优化算法。第一部分解释了如何有效地替换数组中每个元素为其右侧的最大值,包括从后向前遍历以减少计算复杂性的方法。第二部分介绍了如何在保持非零元素相对顺序的同时将数组中的零移到末尾,通过双指针技巧实现原地修改。文章还比较了不同实现的运行时间并提供了改进方案。
摘要由CSDN通过智能技术生成

#1299 Replace Elements with Greatest Element on Right Side

Given an array arr, replace every element in that array with the greatest element among the elements to its right, and replace the last element with -1.

After doing so, return the array.

解题思路:

按照题意,直接for循环改变每一个数,取值于右边最大数。最后一个数 = -1。

class Solution:
    def replaceElements(self, arr: List[int]) -> List[int]:
        for i in range(len(arr)-1):
            arr[i] = max(arr[i+1:])
        arr[len(arr)-1] = -1
        return arr

runtime:

打扰了。不明白为啥那么慢。

看了一下109ms的思路:

 默认最大值是-1,for循环是从后往前。所以等于max()的时候就只要比较两个数值就够了。而我之前从前往后是max()要比较剩下的所有。原来是这样才慢。

重新写一遍。 

class Solution:
    def replaceElements(self, arr: List[int]) -> List[int]:
        maxium = -1
        for i in range(len(arr)-1, -1, -1):
            temp = arr[i]
            arr[i] = maxium
            if temp > maxium:
                maxium = temp
        
        return arr

runtime:

看了discussion forum里 lee215 的解法,更快。不用temp,直接swap。parameter时就默认设置maxium的值为-1。So cool。

class Solution:
    def replaceElements(self, arr: List[int], mx=-1) -> List[int]:
        for i in range(len(arr)-1, -1, -1):
            arr[i], mx = mx, max(mx, arr[i])
        return arr

 runtime:

#283 Move Zeroes

Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.

Note that you must do this in-place without making a copy of the array.

解题思路:

用two pointer法,一个是写入指针 w(rite) ,初始设置为0;一个是读取指针 r(ead),默认为1。

1)先判断写入指针 w 的值是否为零,如果不是,则两个指针都右移一位;如果是,则继续看读取指针的值是否为零。

2)如果读取指针的值不是零,则两值互换后,两个指针都右移一位;如果是零,则读取指针r右移一位,直到读取指针不再是零为止后,让写入指针与读取指针的数值互换。

直到读取指针达到数列的尾端,程序终止。

edge case:数列只有一个元素时,不做任何处理。

class Solution:
    def moveZeroes(self, nums: List[int], w=0, r=1) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        length = len(nums) - 1
        if length > 0:
            while r <= length:
                if nums[w] == 0:
                    if nums[r] != 0:
                        nums[w], nums[r] = nums[r], 0
                        w += 1
                else:
                    w += 1
                    
                r += 1
                

.runtime:

参考discussion forum里ZitaoWang的思路:

也是两指针,不过都从0开始。然后如果所在值非零的话,两个指针一起右移;否则,读取指针右移,写入指针不移。这样会更简洁。连edge case也不用判断。(但是如果两个指针重合的话,就等于白做功?)

重新写一遍:

class Solution:
    def moveZeroes(self, nums: List[int], write=0) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        for read in range(len(nums)):
            if nums[read] != 0:
                nums[write], nums[read] = nums[read], nums[write]
                write += 1

但runtime反而变差了:

无法理解…… 回头再看看。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值