[leetcode刷题系列]Gas Station
2013-09-29 23:38
375 查看
嗯,这是leetcode最新加的一道题目, 也是很经典的算法类的题目了。解法也不止一种。
这里写一下利用双端队列怎么做这道题求出所有的合法的起点把。
1, 单调的双端队列
1)什么是双端队列
双端队列是一个可以在头部和尾部都可以删除和插入元素的队列。站看之下似乎没有什么特别的玄机。但是当我们将其用于扫描一个大小为n的数组,
数组的没个元素都最多进一次,最多被删除一次。那么我们对这个队列的操作复杂度就是N,对双端队列的应用重点就在于何时插入元素,何时删除元素,
以维护某种性质。 接下来我们就用一个例子来介绍单调的双端队列。
2)单调的双端队列
来看一道题目, 对于一个大小为n的数组A,和一个数字m( 1<=m <= n),求出所有的B[i] = min(A[i], A[i +1],..,A[i + m - 1】) (1 <= i <= n - m + 1)。
乍看之下这是一道典型的RMQ的问题,经典的算法都可以在nlogn的时间复杂度下解决这个问题。但是显然这又是一道有自己的特点的RMQ的问题。利用
经典算法必然少挖掘了这个问题的某些特性,尽管经典算法已经做的很好了。下面就介绍如何利用双端队列解决这个问题。
我们建立一个空的双端队列用来保存我们插入其中的数组A的下标,然后开始对数组A进行扫描,假设当前扫描到下表为i的位置,那么如果如果此时
双端队列尾部所保存的下标对应的A数组元素A[deque[tail - 1]] >= A[i]的话, 我们就可以将双端队列尾部元素删除,然后一直循环检测此时双端队列是否
为空或者直到A[deque[tail - 1]] < A[i],那么我们就可以将下表i添加到双端队列的尾部。这样在整个扫描的过程中都可以维持双端队列里保存的下标所对应
的A数组中元素从头到尾是递增的。同时扫描过程中如果i>m,那么我们同时也对双端队列的头部进行检测,如果头部元素的下表< i - m + 1的话,那么我们就
将其从头部删除。这样操作之后, 双端队列里保存的下标都在[i - m + 1, i]之间。同时双端队列的头部保存的下表对应的元素最小。那么就有B[i - m +1] =A[deque[head]]
这样整个扫描过程完成后,就计算出了所有的B[i]。 整个过程中我们对双端队列的操作的时间复杂度是O(n),因为每个元素最多进出一次。所以显然时间复杂度
是O(n).
2, 单调的双端队列在此题的应用。
等明晚把上面两项内容补上。 在这里占个位置先。
这里写一下利用双端队列怎么做这道题求出所有的合法的起点把。
1, 单调的双端队列
1)什么是双端队列
双端队列是一个可以在头部和尾部都可以删除和插入元素的队列。站看之下似乎没有什么特别的玄机。但是当我们将其用于扫描一个大小为n的数组,
数组的没个元素都最多进一次,最多被删除一次。那么我们对这个队列的操作复杂度就是N,对双端队列的应用重点就在于何时插入元素,何时删除元素,
以维护某种性质。 接下来我们就用一个例子来介绍单调的双端队列。
2)单调的双端队列
来看一道题目, 对于一个大小为n的数组A,和一个数字m( 1<=m <= n),求出所有的B[i] = min(A[i], A[i +1],..,A[i + m - 1】) (1 <= i <= n - m + 1)。
乍看之下这是一道典型的RMQ的问题,经典的算法都可以在nlogn的时间复杂度下解决这个问题。但是显然这又是一道有自己的特点的RMQ的问题。利用
经典算法必然少挖掘了这个问题的某些特性,尽管经典算法已经做的很好了。下面就介绍如何利用双端队列解决这个问题。
我们建立一个空的双端队列用来保存我们插入其中的数组A的下标,然后开始对数组A进行扫描,假设当前扫描到下表为i的位置,那么如果如果此时
双端队列尾部所保存的下标对应的A数组元素A[deque[tail - 1]] >= A[i]的话, 我们就可以将双端队列尾部元素删除,然后一直循环检测此时双端队列是否
为空或者直到A[deque[tail - 1]] < A[i],那么我们就可以将下表i添加到双端队列的尾部。这样在整个扫描的过程中都可以维持双端队列里保存的下标所对应
的A数组中元素从头到尾是递增的。同时扫描过程中如果i>m,那么我们同时也对双端队列的头部进行检测,如果头部元素的下表< i - m + 1的话,那么我们就
将其从头部删除。这样操作之后, 双端队列里保存的下标都在[i - m + 1, i]之间。同时双端队列的头部保存的下表对应的元素最小。那么就有B[i - m +1] =A[deque[head]]
这样整个扫描过程完成后,就计算出了所有的B[i]。 整个过程中我们对双端队列的操作的时间复杂度是O(n),因为每个元素最多进出一次。所以显然时间复杂度
是O(n).
2, 单调的双端队列在此题的应用。
等明晚把上面两项内容补上。 在这里占个位置先。
const int MAXN = 1e5 + 10; int head, tail; int deq[MAXN << 1]; int n; int data[MAXN << 1], sum[MAXN << 1]; class Solution { public: int canCompleteCircuit(vector<int> &gas, vector<int> &cost) { // Note: The Solution object is instantiated only once and is reused by each test case. n = gas.size(); for(int i = 0; i < n; ++ i) data[i + 1] = gas[i] - cost[i]; for(int i = 1; i < n; ++ i) data[n + i] = data[i]; sum[0] = 0; for(int i = 1; i < (n << 1); ++ i) sum[i] = sum[i - 1] + data[i]; head = tail = 0; vector<int> ret; for(int i = 1; i < (n << 1); ++ i){ while(head != tail) if(sum[deq[tail - 1]] >= sum[i]) -- tail; else break; deq[tail ++ ] = i; while(head != tail) if(deq[head] < i - n + 1) ++ head; else break; if(i >= n){ if(sum[deq[head]] >= sum[i - n]) ret.push_back(i - n + 1); } } if(ret.size() <= 0) return -1; else return ret[0] - 1; } };
相关文章推荐
- leetcode刷题系列C++-Gas Station
- Gas Station——Leetcode系列(十六)
- LeetCode 2.1.21 Gas Station
- LeetCode 134 Gas Station
- Leetcode之Gas Station
- Leetcode 134 Gas Station
- LeetCode-134. Gas Station(JAVA)加气站问题
- LeetCode(134) Gas Station
- leetcode 日经贴,python code -Gas Station
- leetCode(54):Gas Station
- Gas Station 分类: Leetcode(线性表) 2015-02-15 11:06 40人阅读 评论(0) 收藏
- leetcode Gas Station
- leetcode-Gas Station
- LeetCode Gas Station 两个特性,两种方法完美解答-更新证明方法
- [LeetCode] Gas Station
- leetcode — gas-station
- Gas Station|leetcode题解
- LeetCode 134 - gas station
- LeetCode Gas Station
- LeetCode刷题笔记(贪心):gas-station