您的位置:首页 > 其它

leetcode596:496. Next Greater Element I(寻找元素对应位置的下一个较大值)

2018-02-05 22:38 603 查看
原题:https://leetcode.com/problems/next-greater-element-i/description/

分析:题意是有两个数组,一个数组包含另一个数组中的所有元素,设母数组为M,子数组为N,则求N中的任意一个元素在M中的对应位置之后的大于该元素的值,如果不存在,就返回-1。

Note:

All elements in nums1 and nums2 are unique.

The length of both nums1 and nums2 would not exceed 1000.

第一种方法是暴力搜索,对子数组中的每一个元素,查找在母数组中的对应元素:

vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
vector<int> Next_G_ele;
for (int item : findNums)
{
bool get = false,exist=false;//两个标志,一个确定是否到达该元素位置,一个确定是否存在,不存在添加-1
for (int i = 0; i < nums.size(); i++)
{
if (item == nums[i])
{
get = true;
continue;
}
if (get&&nums[i] > item)
{
Next_G_ele.push_back(nums[i]);
exist = true;
break;
}
}
if (!exist)
{
Next_G_ele.push_back(-1);
}
}
return Next_G_ele;
}


第二种方法是对前一种的改进,利用非连续存储的map结构来快速确定起始搜索位置

#include<unordered_map>//头文件
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
vector<int> Next_G_ele;
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); i++)
map[nums[i]] = i;//建立一个map,便于搜索每一个findNums元素对应的Nums的下标
for (int item : findNums)
{
bool exist=false;
for (int j = map[item]+1; j < nums.size(); j++)
{
if (nums[j] > item)
{
Next_G_ele.push_back(nums[j]);
exist = true;
break;
}
}
if (!exist) Next_G_ele.push_back(-1);
}
return Next_G_ele;
}


第三种方法是利用栈的特性,先对母数组中的元素,每一个元素看他后面是否有大于该数的元素,再对每一个子数组中的元素进行查找,如果有,就是该数,如果没有,就是-1,通过栈与map两种数据结构来提高效率

#include<vector>
#include<unordered_map>
#include<stack>
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
vector<int> Next_G_ele;
unordered_map<int, int> map;
stack<int> sk;
for (int num : nums)
{
while (!sk.empty() && sk.top() < num)//N{ 4, 1, 2 }, M{ 1,3,4,2 ,6}
{
map[sk.top()] = num;
sk.pop();
}
sk.push(num);
}
for (int i : findNums)
{
Next_G_ele.push_back(map.count(i) ? map[i] : -1 );
}
return Next_G_ele;
}


这种方法主要在于用栈来计算每个元素后面的较大元素,这里第一次写成了if,这样相当于只检索了后面一位元素,而用while的时候,是将每一个元素都压入栈,这样,碰到大的元素,将栈内的小于该数的元素都对应到该元素,然后将其排出,这样才能得到正确的map。

三种方法的测试代码:

int main()
{
vector<int> N{ 4, 1, 2 }, M{ 1,3,4, 2 ,6},Next_Greater(N.size());
Next_Greater = nextGreaterElement(N,M);
for (int i : Next_Greater)
cout << i << '\t';
system("pause");
return 0;
}


几个要点:

1、一是代码中使用的是vector的push_back方法,这里不可以指定该vector的大小,否则,前面会用0进行初始化填充。另一种思路是指定大小后,用下标来进行索引。

2、上一点提到的用下表来进行索引时,可以将所有值初始化为-1,这样只需对存在的元素进行更改。

3、map的count方法,也可以用find的迭代器返回值来代替,不知效率孰高孰低,

Next_G_ele.push_back(map.find(i)==map.cend() ? -1 : map[i])
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐