算法设计与分析(七)

39 篇文章 0 订阅
10 篇文章 0 订阅

贪心算法

题目

这次我们选择两题贪心算法作为练习,这两道题目是有关系的,一个是比较基础的贪心,另一个是难一点的贪心。

Jump Game

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.

Determine if you are able to reach the last index.

Example 1:
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

Example 2:
Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximumjump length is 0, which makes it impossible to reach the last index.

Jump Game II

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.

分析

  • Jump Game
    题目的意思是给定一个数组,一个人从起点(小标为0)出发,然后最多走在当前下标的数组元素的步数到达下一个下标,同样走最多当前下标元素对应数组值的步数到达下一个位置,这里需要注意的是不必走完数组值的步数,例如数值为3,你可以选择走一步,两步或者三步,最后看看是否可以有路径到达最后一个顶点。
    在解决这个问题的时候,我们通过维护一个当前可以到达的最远下标,这也是这题贪心的体现所在,然后遍历数组,有下面几种情况:

    • 如果遍历当前下标的值大于当前最大算力,表面这个点是不可达的,直接退出。
    • 如果当前的最大算力大于等于数组长度-1,那么当前的算力可以到达目的,返回true。
    • 如果遍历的当前数组元素的算力大于前一个下标为止的最大算力,更新最大算力。
  • Jump Game II
    这题是上面一题的加强版,在原来的规则下,找出能到达目的需要走的最小步数。
    我们也是维护一个算力值,当我们遍历到某个下标(假设当前元素值为k)的时候,我们遍历从k元素开始的k个元素值个元素,找出接下来K个元素某个点的最大算力,然后我们下一次遍历的起点就是这个最大算力的点,重复上面步骤,直到算力可以到达目标下标。这里的贪心算法的特点体现在当我们遍历到当前数组元素的时候,我们总是找接下来k个元素最大算力的一个,这样就保证了我们找到的路径是最短的。值得注意的是有些特殊的情况,例如一步就能到达目的的,我们的算法不适合,必须从当中分离出来;还有就是我们是以找到最大算力的点的时候记录步数,那么说明最后到达目的的那一步我们没有记录,在返回的时候要记得加上。

源码

  • Jump Game
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int result = 0;
        if(nums.size() == 1) {
        	return true;
        }
        for(int i = 0; i < nums.size() - 1; i++) {
        	if(i > result) {
        		return false;
        	}
        	if(result < nums[i] + i) {
        		result = nums[i] + i;
        	}
        	//cout << result << endl;
        	if(result >= nums.size() - 1) {
        		return true;
        	}
        }
        return false;
    }
};
  • Jump Game II
class Solution {
public:
    int jump(vector<int>& nums) {
        int result = 0, count = 0;
        if(nums.size() == 1) {
        	return 0;
        }
        if(nums.size() != 0) {
        	if(nums[0] + 0 >= nums.size() - 1) {
        		return 1;
        	}
        }
        int max = 0;
        for(int i = 0; i < nums.size() - 1;) {
        	//cout << i << endl;
        	result = nums[i] + i;
        	int tag = 0;
        	int index = i;
        	for(int j = i + 1; j <= nums[i] + i ; j++) {
        		if((nums[j] + j > max)) {
        			max = nums[j] + j;
        			index = j;
        			tag =1;
        		}
        	}

        	//cout << max << endl;
        	if(tag == 1) {
        		count++;
        		result = max;
        		i = index;
        	} else {
        		i++;
        	}
        	//cout << result << endl;
        	if(result >= nums.size() - 1) {
        		break;
        	}
        }
        return count + 1;
    }
};

算法复杂度分析

在Jump Game中,在一次遍历必定能找出来,所以最大的复杂度是O(n);
对于Jump Game II,这个算法的复杂度是不稳定的,在O(n)基础上增加,最好的情况是O(n),这是最好的情况,也就是每次找最大算力的总是最后一个的时候。

更多技术博客https://vilin.club/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值