Leetcode日练笔记21 #724 #747 Find Pivot Index & Largest Number At Least Twice of Others

本文记录了LeetCode中的两道算法题解题思路和优化过程,分别是寻找数组中使左右两边元素之和相等的枢轴索引和确定数组中最大元素是否至少是其他数的两倍。通过讨论不同的解决方案,探讨了如何优化算法的时间复杂度。
摘要由CSDN通过智能技术生成

#724 Find Pivot Index 

Given an array of integers nums, calculate the pivot index of this array.

The pivot index is the index where the sum of all the numbers strictly to the left of the index is equal to the sum of all the numbers strictly to the index's right.

If the index is on the left edge of the array, then the left sum is 0 because there are no elements to the left. This also applies to the right edge of the array.

Return the leftmost pivot index. If no such index exists, return -1.

解题思路:

1. 先求整个数列的和

2.然后for循环range(len(nums))时减去每一项,如果左边的和等于右边的和,那么输出i。

3)循环结束,说明没有pivot,则输出-1。

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        list_sum = sum(nums)
        
        for i in range(len(nums)):
            sum_l = sum(nums[:i])
            total_sum = list_sum - nums[i]
            sum_r = total_sum - sum_l
            if sum_l == sum_r:
                return i
        
        return -1

runtime:

哭了。

想了想,还是因为每往前走一步,都在不断重复算左侧的和sum()。所以有很多多余的步骤。而且这个complexity就是O(n^2)。

再想想别的办法。如果是不停计算左侧的和导致了慢的话,那么改成每往前走一步就+=之前的数呢?这样就是O(N)了。

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        list_sum, sum_l = sum(nums), 0
        
        for i in range(len(nums)):
            total_sum = list_sum - nums[i]
            sum_r = total_sum - sum_l
            if sum_l == sum_r:
                return i
            sum_l += nums[i]
        
        return -1

runtime:

无语,只快了一点点。还有什么地方可以优化呢? 

看了一下前面的solution,132ms的:

已经和我的是几乎一样。不过求sum_r的时候比我少了一步。

再去看看forum的人怎么解:

这样确实会更快,right -= num 比连减两个数值操作会更少一步。

重写了一遍:

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        left, right = 0, sum(nums)
        
        for i, num in enumerate(nums):
            right -= num
            if left == right:
                return i
            left += num
        
        return -1     

runtime:

 #747 Largest Number At Least Twice of Others

You are given an integer array nums where the largest integer is unique.

Determine whether the largest element in the array is at least twice as much as every other number in the array. If it is, return the index of the largest element, or return -1 otherwise.

解题思路:

1.先求出最大值

2.for循环除了最大值以外的数都乘以2,与最大值对比

3.前者大就return -1

4.循环跑完就返回最大值的idx。

class Solution:
    def dominantIndex(self, nums: List[int]) -> int:
        target = max(nums)
        
        for num in nums:
            if num != target:
                if num * 2 > target:
                    return -1
        
        return nums.index(target)

runtime:

emmm, 可优化的话,就是循环前把target拿掉,这样可以减少n步,循环时不用再判断这个数是不是最大值了。不过要先算出最大值的idx,不然一会循环跑完,数列里又被删掉了就再也查不到。再试一下:

class Solution:
    def dominantIndex(self, nums: List[int]) -> int:
        target = max(nums)
        idx = nums.index(target)
        del nums[idx]
        
        for num in nums:
            if num * 2 > target:
                return -1
        
        return idx

runtime:

确实快了不少。想不到其他优化的可能了。看一下别人的答案:

对哦,找到最大值之后,删掉后再找到最大值(为原来第二大的值),直接这个乘以2来判别就可以了。不用每个数都乘以2比较一次,浪费了很多时间。

不过找第二大的值,又要重新跑过一次max(nums),等于循环nums多了一次,所以应该循环一次把最大值和第二大值一起找出来。

class Solution:
    def dominantIndex(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return 0
        
        max1 = max2 = maxi = -1
        for i, num in enumerate(nums):
            if num > max1:
                max1, max2, maxi = num, max1, i
            elif num > max2:
                max2 = num
                
        return maxi if max2 * 2 <= max1 else -1

 可惜最后的runtime跑得不好。反而更慢。看来我还是要好好补一下time complexity的知识了。不然总是不明白为什么跑得慢,怎么优化。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值