LeetCode 496 - Next Greater Element I
LeetCode 503 - Next Greater Element II
LeetCode 556 - Next Greater Element III
https://leetcode.com/problems/next-greater-element-i/
这里是建立每个数字和其右边第一个较大数之间的映射,没有的话就是-1。我们遍历原数组中的所有数字,如果此时栈不为空,且栈顶元素小于当前数字,说明当前数字就是栈顶元素的右边第一个较大数,那么建立二者的映射,并且去除当前栈顶元素,最后将当前遍历到的数字压入栈。当所有数字都建立了映射,那么最后我们可以直接通过哈希表快速的找到子集合中数字的右边较大值
https://discuss.leetcode.com/topic/77916/java-10-lines-linear-time-complexity-o-n-with-explanation
http://bookshadow.com/weblog/2017/02/05/leetcode-next-greater-element-i/
X.
https://discuss.leetcode.com/topic/77868/my-concise-short-solution
http://blog.csdn.net/u014688145/article/details/70254955
我一开始想都没想,针对O(nm)
public int[] nextGreaterElement(int[] findNums, int[] nums) { int[] ans = new int[findNums.length]; for (int i = 0; i < findNums.length; i++) { ans[i] = -1; boolean canFind = false; for (int key : nums) { if (key == findNums[i]) { canFind = true; } if (canFind && key > findNums[i]) { ans[i] = key; break; } } } return ans; }
X.
http://www.cnblogs.com/grandyang/p/6399855.html
先上无脑暴力搜索,遍历子集合中的每一个数字,然后在原数组中找到这个数字,然后向右遍历,找到第一个大于该数字的数即可
X.
我们来对上面的方法稍做优化,我们用哈希表先来建立每个数字和其坐标位置之间的映射,那么我们在遍历子集合中的数字时,就能直接定位到该数字在原数组中的位置,然后再往右边遍历寻找较大数即可
https://discuss.leetcode.com/topic/77904/easy-to-understand-o-mn-java-solution
LeetCode 503 - Next Greater Element II
LeetCode 556 - Next Greater Element III
https://leetcode.com/problems/next-greater-element-i/
You are given two arrays (without duplicates)
nums1
and nums2
where nums1
’s elements are subset of nums2
. Find all the next greater numbers for nums1
's elements in the corresponding places of nums2
.
The Next Greater Number of a number x in
nums1
is the first greater number to its right in nums2
. If it does not exist, output -1 for this number.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. Output: [-1,3,-1] Explanation: For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. For number 1 in the first array, the next greater number for it in the second array is 3. For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4]. Output: [3,-1] Explanation: For number 2 in the first array, the next greater number for it in the second array is 3. For number 4 in the first array, there is no next greater number for it in the second array, so output -1.
Note:
- All elements in
nums1
andnums2
are unique. - The length of both
nums1
andnums2
would not exceed 1000.
这里是建立每个数字和其右边第一个较大数之间的映射,没有的话就是-1。我们遍历原数组中的所有数字,如果此时栈不为空,且栈顶元素小于当前数字,说明当前数字就是栈顶元素的右边第一个较大数,那么建立二者的映射,并且去除当前栈顶元素,最后将当前遍历到的数字压入栈。当所有数字都建立了映射,那么最后我们可以直接通过哈希表快速的找到子集合中数字的右边较大值
https://discuss.leetcode.com/topic/77916/java-10-lines-linear-time-complexity-o-n-with-explanation
Suppose we have a decreasing sequence followed by a greater number
For example
For example
[5, 4, 3, 2, 1, 6]
then the greater number 6
is the next greater element for all previous numbers in the sequence
We use a stack to keep a decreasing sub-sequence, whenever we see a number
For example
The stack will first contain
x
greater than stack.peek()
we pop all elements less than x
and for all the popped ones, their next greater element is x
For example
[9, 8, 7, 3, 2, 1, 6]
The stack will first contain
[9, 8, 7, 3, 2, 1]
and then we see 6
which is greater than 1
so we pop 1 2 3
whose next greater element should be 6
public int[] nextGreaterElement(int[] findNums, int[] nums) {
Map<Integer, Integer> map = new HashMap<>(); // map from x to next greater element of x
Stack<Integer> stack = new Stack<>();
for (int num : nums) {
while (!stack.isEmpty() && stack.peek() < num)
map.put(stack.pop(), num);
stack.push(num);
}
for (int i = 0; i < findNums.length; i++)
findNums[i] = map.getOrDefault(findNums[i], -1);
return findNums;
}
https://discuss.leetcode.com/topic/77880/simple-o-m-n-java-solution-using-stack public int[] nextGreaterElement(int[] findNums, int[] nums) {
int[] ret = new int[findNums.length];
ArrayDeque<Integer> stack = new ArrayDeque<>();
HashMap<Integer, Integer> map = new HashMap<>();
for(int i = nums.length - 1; i >= 0; i--) {
while(!stack.isEmpty() && stack.peek() <= nums[i]) {
stack.pop();
}
if(stack.isEmpty()) map.put(nums[i], -1);
else map.put(nums[i], stack.peek());
stack.push(nums[i]);
}
for(int i = 0; i < findNums.length; i++) {
ret[i] = map.get(findNums[i]);
}
return ret;
}
http://bookshadow.com/weblog/2017/02/05/leetcode-next-greater-element-i/
X.
https://discuss.leetcode.com/topic/77868/my-concise-short-solution
public int[] nextGreaterElement(int[] findNums, int[] nums) {
int n1 = findNums.length, n2 = nums.length;
List<Integer> list = new ArrayList<>();
for (int i : nums) list.add(i);
int[] res = new int[n1];
for (int i = 0; i < n1; i++) {
int cur = findNums[i];
res[i] = -1;
for (int k = list.indexOf(cur); k < n2; k++) {
if (nums[k] > cur){
res[i] = nums[k];
break;
}
}
}
return res;
}
X. Brute Forcehttp://blog.csdn.net/u014688145/article/details/70254955
我一开始想都没想,针对
nums1
的每个元素,循环遍历找nums2
中的next greater
。很明显它的复杂度就是public int[] nextGreaterElement(int[] findNums, int[] nums) { int[] ans = new int[findNums.length]; for (int i = 0; i < findNums.length; i++) { ans[i] = -1; boolean canFind = false; for (int key : nums) { if (key == findNums[i]) { canFind = true; } if (canFind && key > findNums[i]) { ans[i] = key; break; } } } return ans; }
X.
http://www.cnblogs.com/grandyang/p/6399855.html
先上无脑暴力搜索,遍历子集合中的每一个数字,然后在原数组中找到这个数字,然后向右遍历,找到第一个大于该数字的数即可
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) { vector<int> res(findNums.size()); for (int i = 0; i < findNums.size(); ++i) { int j = 0, k = 0; for (; j < nums.size(); ++j) { if (nums[j] == findNums[i]) break; } for (k = j + 1; k < nums.size(); ++k) { if (nums[k] > nums[j]) { res[i] = nums[k]; break; } } if (k == nums.size()) res[i] = -1; } return res; }我们来对上面的方法稍做优化,我们用哈希表先来建立每个数字和其坐标位置之间的映射,那么我们在遍历子集合中的数字时,就能直接定位到该数字在原数组中的位置,然后再往右边遍历寻找较大数即可
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) { vector<int> res(findNums.size()); unordered_map<int, int> m; for (int i = 0; i < nums.size(); ++i) { m[nums[i]] = i; } for (int i = 0; i < findNums.size(); ++i) { res[i] = -1; int start = m[findNums[i]]; for (int j = start + 1; j < nums.size(); ++j) { if (nums[j] > findNums[i]) { res[i] = nums[j]; break; } } } return res; }
X.
我们来对上面的方法稍做优化,我们用哈希表先来建立每个数字和其坐标位置之间的映射,那么我们在遍历子集合中的数字时,就能直接定位到该数字在原数组中的位置,然后再往右边遍历寻找较大数即可
https://discuss.leetcode.com/topic/77904/easy-to-understand-o-mn-java-solution
public int[] nextGreaterElement(int[] findNums, int[] nums) {
if(findNums == null || nums == null ||
findNums.length == 0 || nums.length == 0 ||
findNums.length > nums.length) return new int[0];
int m = findNums.length;
int n = nums.length;
int[] result = new int[m];
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int j = 0; j < n; ++j){
map.put(nums[j], j);
}
for(int i = 0; i < m; ++i){
int j = map.get(findNums[i]);
for(; j < n; ++j){
if(nums[j] > findNums[i]) break;
}
result[i] = j < n ? nums[j] : -1;
}
return result;
}
G家followup: 如果data是stream data怎么改代码和设计输出。