【496】:
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.
【思路】:第一小题属于简单题,都可以写。
class Solution { public: vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) { vector<int> res; for(auto i:findNums){ for(int j = 0; j<nums.size(); ++j){ if(nums[j] == i){ int index = j+1; while(index < nums.size() && nums[index] < i) ++index; if(index == nums.size()) res.push_back(-1); else res.push_back(nums[index]); } } } return res; } };
【503】:
Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.
Example 1:
Input: [1,2,1] Output: [2,-1,2] Explanation: The first 1's next greater number is 2;
The number 2 can't find next greater number;
The second 1's next greater number needs to search circularly, which is also 2.
Note: The length of given array won't exceed 10000.
【思路1】:第二小题要求我们在一个循环数组里面对每个数找到下一个更大的数。
看到循环数组首先我们可以想到把整个数组叠加两次在对index取余就能实现相应的查找
直接的暴力查找当然理论上也是可行的,只不过时间复杂度为O(n^2),在数据量达到10000的时候有点力不从心,
显然暴力搜索里面存在着大量的重复搜索,所以我们要做的就是找到这些重复的工作并消除他们。
我自己的做法【区间跳跃】:因为需要找到下一个比原数据大的数,所以我们可以考虑从右往前搜索,往前的搜索就能使用右侧已经搜索过的数据了
具体就是查找右侧数据时若数据比当前值小,则直接跳到比该值大的数的地方(从右往前保证右侧先搜索),从而减少查找次数。
代码1【100ms,Beat 75.12%】:
class Solution { public: vector<int> nextGreaterElements(vector<int>& nums) { int s = nums.size(); vector<int> index_save(s,-1); for(int index = s-1; index >= 0; --index){//从右往前搜索,通过index跳跃减少搜索次数 for(int i = 1,count = 0; count < s ; ++i,++count){//count计数查找次数,防止无限循环 int index_temp = (index+i)%s; if(nums[index_temp] > nums[index]) {//找到则直接赋值退出内层循环 index_save[index] = index_temp; break; } if(index_save[index_temp] != -1){//存在已经查找到的数,直接跳跃 i = index_save[index_temp] - index - 1;//注意这里的跳跃坐标 } } } for(int i = 0; i<s; ++i){ if(index_save[i] != -1) index_save[i] = nums[index_save[i]]; } return index_save; } };
【思路2】网上能查找到的关于这道题的解法主要是使用一个栈,在遍历数组的过程中找到右侧第一个更大的数,当然循环数组需要查询2遍。
想到了这一点其实思路和代码都要比前面的一种思路简单。
代码2:
class Solution { public: vector<int> nextGreaterElements(vector<int>& nums) { int n = nums.size(); vector<int> res(n, -1); stack<int> st; for (int i = 0; i < 2 * n; ++i) { int num = nums[i % n]; while (!st.empty() && nums[st.top()] < num) {//把所有能弹出的答案弹出! res[st.top()] = num; st.pop(); } if (i < n) st.push(i); } return res; } };
感觉这道题目就是栈的使用,很巧妙的解法。