欢乐力扣11-15


1、前言

 本篇继续整理Hot150


1、H指数

1.1.描述

 给定一个数组,里面每个元素表示作者论文的引用数量。H指数:表示发表了H篇论文,且有H篇论文被引用了H次。返回H中最大的那个值。

1.2.思路

 题目描述比较混乱,直接说思路,由大到小排序,然后遍历每个元素,当元素值>i时,则累加H指数。

class Solution:
    def hIndex(self, citations: List[int]) -> int:
        citations.sort(reverse=True)
        h = 0
        for i in range(len(citations)):
            if citations[i] > i :  # 这里到底是 > 还是 >= 可能拿捏不准,记住[0]这个例子,h=0;
                h += 1
            else:
                break 
        return h 

2、除自身以外数组的乘积

2.1.描述

 给你一个数组Nums,返回一个ans数组,里面每个元素表示nums数组中除了自身以外,其余元素的乘积:举个例子:

nums=[1,2,3],返回ans=[6,3,2]

2.2.思路

 首先存储下来当前元素,所有左边元素的乘积和右边元素的乘积。然后分别从左右两边取元素便能得到ans的乘积。

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        # 左边元素所有乘积
        left = []
        for i in range(len(nums)):
            if i == 0:
                left.append(1)
            else:
                ele = nums[i-1] * left[i-1]
                left.append(ele) 
        # 右边元素所有乘积
        right = []
        for i in range(len(nums)-1, -1, -1):
            if i == len(nums) - 1:
                right.append(1)
            else:
                # i的后一个坐标
                ele = nums[i+1] * right[len(nums)-2-i] 
                right.append(ele)
        # 遍历每个元素
        ans = []
        for l, r in zip(left, right[::-1]):
            ans.append(l*r)
        return ans 

3、加油站

3.1.描述

 给定一个加油的数组 和 去下个加油站的耗油数组,问从哪个加油站出发,能够完整的循环一圈?

3.2.思路

 上来先判断,若总的加油数组和比总的耗油数组和小,则一定不够行驶一圈,直接返回-1;假设从i站出发,能行驶到j站,但是行驶不到j+1站;则将起始位置调整为j+1站,继续循环。

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        if sum(gas) < sum(cost) : return -1
        start_idx = 0 # 起始位置
        curSum = 0    # 从i到j的累加加油和
        for i in range(0, len(gas)):
            if curSum < 0:
                curSum = 0 
                start_idx = (i) % len(gas) # 若不满足,则将起始位置调整为下一站;
            curSum += (gas[i] - cost[i] )  # 累加
        return start_idx

4、分发糖果

4.1.描述

 N个孩子站成一排,有个分数数组,现在要求给每个孩子按照分数分发糖果,要求:每个孩子至少有一个糖果;得分高的孩子需要比得分低的孩子糖果多。返回至少得发多少个糖果?

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

4.2.思路

 将问题拆分成两个问题:先遍历满足左规则:即若右边孩子比左边孩子得分高,就比左边孩子多一个糖果;否则仅给一个。然后在相反遍历右规则,最后同时遍历左右规则,取最大的糖果数目累加即可。

class Solution:
    def candy(self, ratings: List[int]) -> int:
        # 左遍历:若右边孩子比左边孩子分数高,则多发一个糖果
        left = []
        for i in range(len(ratings)):
            if i == 0:
                left.append(1)  # 初始孩子手里有一个糖果
            else:
                if ratings[i] > ratings[i-1]:
                    left.append(left[i-1]+1)
                else:
                    left.append(1)
        right = []
        for i in range(len(ratings)-1, -1, -1):
            if i == len(ratings) - 1:
                right.append(1)
            else:
                if ratings[i] > ratings[i+1]:
                    right.append(right[len(ratings)-1-1-i]+1)
                else:
                    right.append(1)
        # 当前这个孩子需要同时满足左右两边规则
        ans = 0 
        for l,r in zip(left, right[::-1]):
            ans += (max(l, r))
        return ans 

5、接雨水

5.1.描述

 给定一个高度数组,问由这些高度导致的低洼能接多少单位雨水?宽度为1。

5.2.思路

 从左遍历记录最高高度,从右遍历记录最高高度。然后二者取最小值减去当前高度即是接雨水的高度。示例图可参考官方题解。

class Solution:
    def trap(self, height: List[int]) -> int:
        # 记录从左到右的最大高度
        leftmax = []
        for i in range(len(height)):
            if i == 0:
                leftmax.append(height[0])
            else:
                leftmax.append(max(height[i], leftmax[i-1]))
        # 记录从右到左的最大高度
        rightmax = []
        for i in range(len(height)-1, -1, -1):
            if i == len(height) -1 :
                rightmax.append(height[-1])
            else:
                rightmax.append(max(rightmax[len(height)-1-1-i],  height[i]))
        # 遍历,取二者最小值
        ans = 0 
        for i in range(len(height)):
            max_l = leftmax[i]
            max_r = rightmax[len(height)-1-i]
            ans += (min(max_l, max_r) - height[i])  # 取出二者最小值,减去当前高度
        return ans 

总结

 15道了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值