【LeetCode刷题】第一期

一:1248.统计[优美子数组](中等)

题目描述:传送门

法一:暴力求解
思路:把所有子数组列出来,再遍历一遍,看其中满足条件的有几个

def is_odd(n):
    return 1 if n%2 == 1 else 0

def odd_num(array):
    count = 0
    for i in array:
        if is_odd(i):
            count += 1
    return count

class Solution:
    def numberOfSubarrays(self, nums: List[int], k: int) -> int:

        children = []
        count = 0
        # 求出所有子数组
        for i in range(len(nums)):
            for j in range(i, len(nums)):
                children.append(nums[i:j+1])
        # print(children)
        for i in range(len(children)):
            if odd_num(children[i]) == k:
                count += 1
        return count

时间复杂度:O(n^2)
当然,这种做法会超出时间限制。

法二:数学
解析可参考leetcode上,这里需要说明的是,之所以要在odds开头和结尾加一个-1和原数组长,就是为了处理边界的情况。

  • 假设第一个奇数是i,那么对应的优美子数组的左侧就应该有i+1种情况。比如[2,4,1,1,3,4,5,6,7,3,2],第一个奇数的下标是2,但是第一个奇数为原数组中第三个1的优美子数组的左侧有[1],[4,1].[2,4,1]三种情况,所以2+1才是正解
  • 假设最后一个不是奇数,那么也要考虑最后一个奇数到原数组最后一个位置有n-最后一个奇数下标种情况
class Solution:
    def numberOfSubarrays(self, nums: List[int], k: int) -> int:
        ans = 0       # 最终的结果
        odds = [-1]   # 存放所有奇数的下标,这里先存放一个-1,这样后面的数减去它的时候就相当于+1
        for index, num in enumerate(nums):
            if num % 2 == 1:
                odds.append(index)
        odds.append(len(nums))   # 存放一个总长度
        for i in range(1, len(odds)-k):
            ans += (odds[i] - odds[i-1])*(odds[i+k] - odds[i+k-1])
        return ans

在这里插入图片描述
时间复杂度:O(n)
空间复杂度:O(n)
法三:前缀和
待做

二:26.删除排序数组中的重复项(简单)

思路:双指针。因为输出是原数组里的不重复数字的个数,且原数组已排序。所以只需要两个指针,一个负责记录以及去重,一个负责往后遍历。

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        i = 0
        for j in range(1, len(nums)):
            if nums[i] != nums[j]:
                i += 1
                nums[i] = nums[j]
        return i+1

在这里插入图片描述

三:1672.最富有客户的资产总量(简单)

class Solution:
    def maximumWealth(self, accounts: List[List[int]]) -> int:
        ans = 0
        for i in range(len(accounts)):
            temp = sum(accounts[i])
            if temp > ans:
                ans = temp
        return ans

题目很简单,for循环里面嵌套sum求和,复杂度挺高的。
在这里插入图片描述

四:1480.一维数组的动态和(简单)

class Solution:
    def runningSum(self, nums: List[int]) -> List[int]:
        ans = [nums[0]]
        for i in range(1, len(nums)):
            ans.append(ans[i-1] + nums[i])
        return ans

在这里插入图片描述

优化:直接在原数组上进行操作:

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

在这里插入图片描述

五:1512.好数对的数目

1.暴力解法

class Solution:
    def numIdenticalPairs(self, nums: List[int]) -> int:
        count = 0
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[j] == nums[i]:
                    count += 1
        return count

在这里插入图片描述
2.优化
思路:在整个数组中,我们只需要知道每一个数对应的个数,然后相当于在k个相同的数中任意取两个,就是 C k 2 C_{k}^2 Ck2。所以第一步优化可以先使用字典统计每一个数出现的个数,之后使用公式计算。
但是,由于 C k 2 = k ( k − 1 ) 2 = 1 + 2 + 3 + ⋅ ⋅ ⋅ + ( k − 1 ) C_{k}^2=\frac{k(k-1)}{2}=1+2+3+···+(k-1) Ck2=2k(k1)=1+2+3++k1

一个数第一次出现: C 1 2 = 0 C_{1}^2=0 C12=0
第二次出现, C 2 2 = 1 C_{2}^2=1 C22=1
第三次出现, C 3 2 = 3 C_{3}^2=3 C32=3
第四次出现, C 4 2 = 6 C_{4}^2=6 C42=6
第五次出现, C 5 2 = 10 C_{5}^2=10 C52=10
发现没有,第一次是0,第二次是0+1,第三次是0+1+2,第四次是0+1+2+3,第五次是0+1+2+3+4。以此类推。这样一来,我们可以建立一个全0数组,依次遍历,给计数的count加上该数对应位置数字的统计数,然后,在该数对应的位置加1(类似字典),以便下次加在统计数上。

class Solution:
    def numIdenticalPairs(self, nums: List[int]) -> int:
        count = 0
        temp = [0] * 100
        for i in nums:
            count += temp[i-1]
            temp[i-1] += 1
        return count

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值