数据结构和算法经典100题-第21题
2015-12-16 10:56
525 查看
题目要求:
给定数组arr,arr[i] == k代表可以从位置i向右跳1~k个距离,比如,arr[2] == 3,代表从位置2可以跳到位置3、位置4或位置5,如果从位置0出发,返回最少跳几次能跳到arr最后的位置上?
解析:
思路:可以考虑从两个角度解决这个问题,关键在于选择参考标准,第一种可以把这个问题归结为到达每个固定坐标至少需要多少步。显然不符合贪心条件,想到用动态规划打表解决。OK这是一种思路。
从另一个角度观察此问题,此问题可以总结为跳跃X步最远能到哪的问题,只要满足X步最远能到的坐标大于等于所求的坐标就可以。下面根据这两个思路分别给出代码和复杂度分析。
思路一:动态规划:
头文件
可以看到打印结果是3步,是正确的,但时间复杂度是O(N^2),空间复杂度是O(N)
接下来看第二种思路。
第一种方法时间复杂度是O(N^2),空间复杂度是O(N);
可以看到第二种方法的时间复杂度是O(N),空间复杂度是O(1)。
所以第二种方法更优。
OKay,路漫漫其修远兮
给定数组arr,arr[i] == k代表可以从位置i向右跳1~k个距离,比如,arr[2] == 3,代表从位置2可以跳到位置3、位置4或位置5,如果从位置0出发,返回最少跳几次能跳到arr最后的位置上?
解析:
思路:可以考虑从两个角度解决这个问题,关键在于选择参考标准,第一种可以把这个问题归结为到达每个固定坐标至少需要多少步。显然不符合贪心条件,想到用动态规划打表解决。OK这是一种思路。
从另一个角度观察此问题,此问题可以总结为跳跃X步最远能到哪的问题,只要满足X步最远能到的坐标大于等于所求的坐标就可以。下面根据这两个思路分别给出代码和复杂度分析。
思路一:动态规划:
头文件
#ifndef _ALG_15TH_H_ #define _ALG_15TH_H_ #include <vector> #define MAX_STEPS 65535 class SkipArray { public: SkipArray(); ~SkipArray(); int minStep(std::vector<int> &inputArray); int minStep(std::vector<int> &inputArray, std::vector<int> &path); }; #endif
#include <stdio.h> #include <iostream> #include <vector> #ifdef _METHOLD_1_ #include "15.h" using namespace std; SkipArray::SkipArray() {} SkipArray::~SkipArray() {} int SkipArray::minStep(std::vector<int> &inputArray) { int size = inputArray.size(); if (0 == size || 65535 < size) { cout<<"minStep --inputArray is illegal."<<endl; return 0; } vector<int> steps; for (int i = 0; i < size; ++i) { steps.push_back(MAX_STEPS); } // O(N^2) steps[0] = 0; for (int i = 0; i < (int)size; ++i) { for (int j = 0; j <= inputArray[i]; ++j) { if (steps[i+j] > steps[i] + 1) { steps[i+j] = steps[i] + 1; } } } for (int i = 0; i < size; i++) { cout<<"steps["<<i<<"] = "<<steps[i]<<endl; } return steps[9]; } int main(void) { int iarray[] = {3,3,2,5,1,1,1,1,1,1}; size_t count = sizeof(iarray)/sizeof(int); vector<int> ivec(iarray,iarray+count); SkipArray skipArray; count = skipArray.minStep(ivec); // count = minStep(ivec); // cout<<"Min steps = "<<count<<endl; return 0; }
可以看到打印结果是3步,是正确的,但时间复杂度是O(N^2),空间复杂度是O(N)
接下来看第二种思路。
int minStep(std::vector<int> &array) { if (array.empty()) { cout<<"minStep array is empty."<<endl; return 0; } int current = 0; int jump = 0; int next = 0; int tmp = 0; int size = (int)array.size(); //next = array[0]; cout<<"array size = "<<size<<endl; // 时间复杂度O(N),空间复杂度O(1) for (int i = 0; i < size; ++i) { if (next >= size - 1) { return current+1; } if (jump >= i) { int tmp = array[i] + i; next = (next < tmp) ? tmp : next; } else { current++; jump = next; } } return current; } int main(void) { int iarray[] = {3,3,2,5,1,1,1,1,1,1}; size_t count = sizeof(iarray)/sizeof(int); vector<int> ivec(iarray,iarray+count); // SkipArray skipArray; // count = skipArray.minStep(ivec); count = minStep(ivec); cout<<"Min steps = "<<count<<endl; return 0; }
第一种方法时间复杂度是O(N^2),空间复杂度是O(N);
可以看到第二种方法的时间复杂度是O(N),空间复杂度是O(1)。
所以第二种方法更优。
OKay,路漫漫其修远兮
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 数据结构之Treap详解
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解