单调栈——数组中找出每个数后面比它大的数中最小的那个 odd even jump

时间:2019-03-14
本文章向大家介绍单调栈——数组中找出每个数后面比它大的数中最小的那个 odd even jump,主要包括单调栈——数组中找出每个数后面比它大的数中最小的那个 odd even jump使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

数组中找出每个数后面比它大的数中最小的那个;

数组中找出每个数后面比它小的数中最大的那个。


给定一个整数数组A。从某一些起始索引,你可以做一系列的跳跃。其中的(第1,第3,第5 ......)跳跃称为奇数跳跃,(第2,第4,第6 ......)跳跃称为偶数跳跃

你可以从索引i 以下列方式跳转到索引 j(i <j):

在奇数跳跃(即跳跃1,3,5,...)期间,跳转到索引j,使得A [i] <= A [j]并且A [j]是可能的最小值。如果有多个这样的索引j,则只能跳转到最小的索引 j。 在偶数跳跃(即跳跃2,4,6,...)期间,跳转到索引j,使得A [i]> = A [j],A [j]是最大的可能值。如果有多个这样的索引j,则只能跳转到最小的索引 j。(可能存在某些索引,不存在合法的跳跃)
如果从该索引开始,您可以通过跳转一些次数(大于等于0次)到达数组的末尾(索引A.length - 1),那么这是一个有效的起始索引


方法一单调栈:

 1 class Solution:
 2     """
 3     @param A: An integer array A
 4     @return: Return the number of good starting indexes
 5     """
 6     def oddEvenJumps(self, A):
 7         # Write your code here
 8         stack, array, upper = [], sorted([(a, i) for i, a in enumerate(A)]), [-1 for i in range(len(A))]
 9         for num, i in array:
10             while len(stack) > 0 and stack[-1] < i:
11                 upper[stack.pop()] = i
12             stack.append(i)
13             
14         stack, array, lower = [], sorted([(-a, i) for i, a in enumerate(A)]), [-1 for i in range(len(A))]
15         for num, i in array:
16             while len(stack) > 0 and stack[-1] < i:
17                 lower[stack.pop()] = i
18             stack.append(i)
19             
20         odd, even = [0 for i in range(len(A))], [0 for i in range(len(A))]
21         odd[len(A) - 1], even[len(A) - 1] = 1, 1
22         
23         ans = 0
24         for i in range(len(A) - 1, -1, -1):
25             if upper[i] != -1:
26                 odd[i] = even[upper[i]]
27             if lower[i] != -1:
28                 even[i] = odd[lower[i]]
29             ans += odd[i]
30         
31         return ans

方法二:

用treemap来做,给定一个数(key),去map中找upper_bound第一个大于key的,以及lower_bound第一个大于等于key的。

 1 class Solution {
 2 public:
 3     /**
 4      * @param A: An integer array A
 5      * @return: Return the number of good starting indexes
 6      */
 7     int oddEvenJumps(vector<int> &A) {
 8         // Write your code here
 9         vector<int> upper(A.size(), -1);
10         vector<int> lower(A.size(), -1);
11         
12         map<int, int> mapNumToIndex;
13         
14         for(int i = A.size() - 1; i >= 0; i--){
15             map<int, int>::iterator lowerBound = mapNumToIndex.lower_bound(A[i]);
16             
17             if(lowerBound != mapNumToIndex.end()) {
18                 upper[i] = lowerBound->second;
19             }
20             
21             if(lowerBound != mapNumToIndex.end() && lowerBound->first == A[i]) lower[i] = lowerBound->second;
22             else if(lowerBound != mapNumToIndex.begin()) lower[i] = (--lowerBound)->second;
23             
24             mapNumToIndex[A[i]] = i;
25         }
26         
27         vector<int> odd(A.size(), 0);
28         vector<int> even(A.size(), 0);
29         odd[A.size() - 1] = even[A.size() - 1] = 1;
30         
31         int ans = 1;
32         for(int i = A.size() - 2; i >= 0; i--){
33             if(upper[i] != -1) odd[i] = even[upper[i]];
34             if(lower[i] != -1) even[i] = odd[lower[i]];
35             ans += odd[i];
36         }
37         return ans;
38     }
39 };