算法设计与分析:Jump Game II(Week 7)

学号:16340008

题目:Jump Game II


Question:

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

Example:

Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2.
    Jump 1 step from index 0 to 1, then 3 steps to the last index.

Note:

You can assume that you can always reach the last index.


Answer:

 题目是从Greedy分类中找到的。题意为:给一串非负数组num,从下标0开始,每次能从第i位最多跳num[i]步,到第i+num[i]位,求从下标0开始跳若干次到数组末尾所用的最少步数。起初的思路并没有贪心算法的思想。算法如下:

  1. 创建数组steps,以及变量 i, j = 0
  2. 判断nums[i],若非0则刷新steps[i+1]到steps[i+nums[i]+1]的最小步数(step[i]+1与原值之间取最小值)
  3. 重复步骤2,直到 i + nums[i] + 1 == sizeof(num) - 1

这个算法省略了一些细节,但主要思路就是遍历数组nums的每个值,并不断修正其能到达的位置的最小步数,直到能到达尾部。算法的时间复杂度最低能到O(1),但是当数组情况特殊时,即除了最后一步,每一步都最远都只能去到末尾前一位时,复杂度将是O(n^2)。初步代码如下(python3):

class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n == 1 or n == 0:
            return 0
        steps = [0] * n
        for i in range(n):
            for j in range(nums[i]):
                if i + j + 1 >= n:
                    break
                if i + j + 1 == n - 1:
                    return steps[i] + 1
                if steps[i+j+1] == 0:
                    steps[i+j+1] = steps[i] + 1
                else:
                    steps[i+j+1] = min(steps[i+j+1], steps[i] + 1)

本地测试代码如下:

test = Solution()
nums = [2,3,1,1,4]
print(test.jump(nums))

 然而提交时遇到了TLE:

这里便是上文提到的极端情况。上面的算法实际上有很多不需要的计算,例如到不必经过的位的步数计算,以及不同起跳点到同一位置的重复运算。由于题目是贪心算法分类的,于是从贪心算法的思想入手。贪心算法需要考虑当前的每个选择的价值,总是做出在当前看来是最好的选择。然而显然单纯的每次跳最远并不是最佳的(如[3,5,5,1,1,1,1]),因此我们对每个选择的优劣要有更远的判断。对当前能到的每个位置而言,所选的位置下一步能跳到最远的那一个(不是该位置能跳的距离最远,而是落地点相比较),即是最优的选择。假设选择A的下一步能跳到最远,任何其他选择中的其中一个选择B的下一步能到的位置要消耗1步,而A到这些位置也是1步,但A比B远的部分,B要2步或更多,A仍然是1步。因此核心算法如下:

  1. 对nums[i],如果nums[i]+i >= length,则返回step
  2. 遍历nums[i+1]到nums[i+nums[i]],以上述方法选出最优位置nums[j],step++,以nums[j]作为标准重复1,2步

代码如下(python3):

class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n == 1 or n == 0:
            return 0
        step = 0
        i = 0
        while i < n:
            step += 1
            if nums[i] + i >= n - 1:
                return step
            maxI = 0
            temp = 0
            for j in range(nums[i]):
                if maxI < nums[i + j + 1] + j:
                    maxI = nums[i + j + 1] + j
                    temp = j
            i += temp + 1

 最终优化效果理想:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 大整数的加减乘除运算是算法设计与分析中的一个重要问题。对于大整数的加减乘除运算,需要设计高效的算法来处理。其中,加法和减法可以采用类似于小学数学中的竖式计算方法,乘法可以采用类似于小学数学中的乘法计算方法,而除法则需要采用更为复杂的算法,如长除法或牛顿迭代法等。在算法设计与分析中,需要考虑算法的时间复杂度和空间复杂度,以及算法的正确性和稳定性等问题。同时,还需要考虑算法的实际应用场景,如密码学、计算机图形学、计算机视觉等领域,以便选择合适的算法。 ### 回答2: 随着计算机科学和技术的不断发展,大整数计算逐渐成为计算机科学中的一个重要问题。 在日常生活中,我们经常需要处理大数的加减乘除,例如:财务管理、密码学、科学计算等。这些雄厚的数字往往需要通过一些算法进行高效的计算,这就需要一些针对大整数的算法设计与分析。 大整数加法:大整数加法其实就是小学数学中的竖式加法。我们可以先将两个大数的最低位相加,将结果的个位保存下来,然后将得到的进位加到下一位的计算中,直到所有位数都加完。 大整数减法:大整数减法可以通过加上相反数来实现。具体来说,我们将被减数和减数的位数对齐,然后按位进行减法操作。需要注意的是,如果被减数小于减数,则需要借位。 大整数乘法:大整数乘法一般采用传统的乘法规则:将两个数的每一位相乘,并保持结果在正确的位上。需要注意的是,乘法可以通过使用一些技巧来加速计算,例如:Karatsuba算法和分治法。 大整数除法:大整数除法一般采用长除法或者二分法进行。长除法与小学时候学习的是一样的,通过将被除数的一位一位与除数对齐,然后逐个相除。二分法则通过不断地将除数倍增来加速计算。 总而言之,针对大整数的加减乘除运算需要使用一些高效的算法来进行计算。这些算法的设计和分析将会涉及到大量的数学原理和计算机科学的知识。同时,算法的实现也需要考虑到程序的效率和正确性。 ### 回答3: 随着计算机科学的发展,数字运算一直是算法设计和分析中应该掌握的基础部分。除了基本的整数运算,对于大整数的加、减、乘、除等运算也非常重要。大整数的运算是指超过计算机原始字长的整数的运算。 对于大整数的加、减、乘、除,我们需要使用不同的算法来执行。以下是针对大整数的四种运算的算法简介: 大整数加法:大整数加法的基本思路很简单:将大整数分割成同样长度的数字部分并对相应的数字部分执行加法运算。如果有进位,进位值将被带入下一位的计算中。最终结果是一个大整数。 大整数减法:大整数减法比加法稍微复杂一些。常用的方法是将 位权相同的两个位数相减。如果被减数小于减数,则需要进行借位。借位意味着从高位借一位,同时在当前位减去10。如果需要多次借位,就需要连续地对更高的位进行借位操作。 大整数乘法:用笔和纸做乘法的方法是讲算术方法还原成使用乘法表,那在算法设计中我们就可以使用竖式乘法。在这种方法中,使用被乘数和乘数的每一位进行部分乘法计算,并将结果加起来。这种方法可以极大地降低计算量。 大整数除法:除法在大整数中是最棘手的运算。可以将从左到右的数字逐位与除数相除。如果它小于除数,则将下一位的数字添加到被除数中。具体的除数和被除数都需要调整,以确保它们具有相同的数字长度。最终结果是商和余数。 总之,算法设计和分析中大整数的加、减、乘、除是非常重要的部分。在实际项目中,大整数的四种运算也经常出现。所以我们必须理解这些算法并熟练掌握它们。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值