刷Leetcode算法的第十八天

序言

题目:
公司安排2N个人参加面试。第i个人坐飞机飞到城市A的费用为costs[i][0],飞到城市B的费用为 costs[i][1]。
返回安排好每个人都前往某城市面试的最低费用,A、B城市各有N个人参加, 问最低的成本是多少

例子:

输入:[[10,20],[30,200],[400,50],[30,20]]
输出:[[400, 50], [30, 20], [10, 20], [30, 200]]

这里的思路是 让数组按照 两值相差 来排序
比如让去A城市的费用减去 B城市的费用,并按照这个差值排序,所以当差值小的时候,理所当然应该去A城市,如果差值大的话,应该去B城市,所以从小到大排序后的前N个 应该去A城市,后N个去B城市。

def interview(costs):
    cost = 0 
    #按照差值排序
    costs.sort(key = lambda x : x[0]-x[1])
    #从小到大排序后的前N个 应该去A城市,后N个去B城市
    N = len(costs)//2
    for i in range(N):
        cost  += (costs[i][0]  + costs[i+N][1])
    return cost    	

LT题目–55 跳跃游戏I
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标

例子

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 13 步到达最后一个下标

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标

    def canJump(nums):
        N = len(nums)
        long_index = 0 
        for i in range(N):
            if i <= long_index:
                long_index = max(long_index, i + nums[i])
                if long_index >= n - 1: return True
                #结束条件 
        return False

假设一个例子:
数组为: [2, 3,1,1,4,1,2,3,1,1,2,1]
那么会怎么跳跃呢? 终止跳跃的条件是 long_index >= N-1

开始的时候:
初始化 long_index = 0

for i = 0 时候
满足 i=0 <= long_index ,long_index = max(0, i + nums[i] ) = 2
在这个循环中,最长可到的位置由 0 变成 2

数值231141231121
位置01234567891011
long_index最长可到的位置

for i = 1时候
满足 i=1 <= long_index= 2
对于 i = 1 时候: long_index = max(2, i + nums[i]) = max(2, 1+ 3) = 4
在这个循环中,最长可到的距离由 2 变成 4

数值231141231121
位置01234567891011
long_index最长可到的位置

for i= 2的时候
满足 i=2 <= long_index= 4
long_index = max(4, i + nums[i])= max(4, 2+ 1) = 4
在这个循环中 最长可到的位置还是 4

for i= 3的时候
i = 3 满足 小于 最长位置4
long_index = max(4, i + nums[i]) = max(4,4) = 4
所以最长可到的位置还是 4

for i = 4 的时候
i = 4 满足 小于或等于 4 ,
long_index = max(4, i + nums[i]) = max(4, 8) = 8
现在最长可到的距离由4变成 8

数值231141231121
位置01234567891011
long_index最长可到的位置

for i = 5的时候
long_index = max(8, i + nums[i]) = max(8, 6) = 8
还是8

for i = 6 的时候
long_index = max(8, i + nums[i]) = max(8,8) = 8
还是8

for i = 7 的时候
long_index = max(8, i + nums[i]) = max(8,10) = 10
最长可到的位置是由8变成10

数值231141231121
位置01234567891011
long_index最长可到的位置

for i = 8 的时候
long_index = max(10, i + nums[i]) = max(10,9) = 10
还是 10

for i = 9 的时候
long_index = max(10, i + nums[i]) = max(10,10) = 10
还是10

for i = 10的时候
long_index = max(10, i + nums[i]) = max(10,12) = 12 > 11
满足结束条件,结束。


进阶题:

LT题目–45 跳跃游戏II
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置

例子如下:

输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置】
     
输入: [2,3,0,1,4]
输出: 2
class Solution:
    def jump(self, nums: List[int]) -> int:

        N = len(nums)
        pre = -1 
        long_index = 0 
        step = 0

        for i in range(N):
            if long_index >= N-1: 
                return step
            elif pre < i <= long_index:
                step += 1 
                pre = long_index
            long_index = max(long_index, i+nums[i])
        return step

举个例子说明
nums = [7, 0, 9, 6, 9, 6, 1, 7, 9, 0, 1, 2, 9, 0, 3]
首先初始化,
pre = -1
long_index = 1

for i = 0的时候
由于 -1 < i <= 0
step = 1 ; pre = long_index = 0
long_index = max(0, i+nums[i]) = max(0, 7) = 7
最长能到的位置是7

数值709696179012903
位置01234567891011121314

for i = 1 的时候
也满足 pre=0 < i <=long_index = 7
所以 step += 1 = 2; pre = long_index = 7
long_index = max(7, i+nums[i]) = max(7, 1+0) = 7
最长位置还是7

for i = 2的时候
就不满足 pre = 7 < i <= 7
直接到 long_index = max(7, i+nums[i]) = max(7, 2+ 9)= 11
所以最长能到的位置是 11

数值709696179012903
位置01234567891011121314

同理, for i = 3,4,5,6,7的时候,也不会满足pre < i <= long_index这个条件,因为pre都为7了
即不会再对step加一,也不会赋值给pre
所以只会不断的更新 long_index 取最大值,即14是最大的 刚好14 >= N-1 即可return step=2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值