1.[496]下一个更大元素I
解题记录:
1.这道题可以用暴力解法,每一个nums1的元素都遍历一次nums2的元素,时间复杂度为O(len1*len2)。
2.这一篇博主要是学习单调栈问题的解法,利用栈的特点,定义单调栈,当新元素的值大于栈顶元素的值的时候,将栈顶元素弹出,并记录在哈希表中,栈顶元素为索引值(题目中给出元素最大为10^4,因此哈希表空间可以设为10000的大小),新元素为value值,也就是下一个更大元素。
3.当新元素小于栈顶元素的时候,可以直接入栈,这样形成的栈为单调递增栈。最后当nums2没有元素可以入栈的时候,栈中的元素都没有下一个更大的值了,可以直接出栈并将哈希表中对应值设置为-1。
4.最后只需要查找哈希表索引对应的值即可得到下一个更大元素。这样的时间复杂度为O(len1+len2)。
C语言代码:
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int i, top = -1;
int *res = (int*)malloc(sizeof(int) * nums1Size);
int *stack = (int*)malloc(sizeof(int) * nums2Size); //单调栈
int *hashmap = (int*)malloc(sizeof(int) * 10000); //以nums2元素为索引的哈希表
//遍历数组2,记录每个元素的下一个更大元素
for (i = 0; i < nums2Size; i++)
{
if (top == -1) //如果为空栈,直接入栈
stack[++top] = nums2[i];
else{
while (top >= 0)
{ //只要新元素大于栈顶元素,则出栈且记录进哈希表
if (nums2[i] > stack[top])
hashmap[stack[top--]] = nums2[i];
else
break;
}
//不管是弹栈后记录进哈希表,还是可以直接入栈,都需要把新元素入栈
stack[++top] = nums2[i];
}
}
while (top >= 0) //把栈中剩余元素的哈希表值设为-1
hashmap[stack[top--]] = -1;
for (i = 0; i < nums1Size; i++)
res[i] = hashmap[nums1[i]];
*returnSize = nums1Size;
return res;
}
2.[503]下一个更大元素II
解题记录:
1.本题和上一题非常相似,但区别就在于是循环数组,后面的元素可以找到在其之前的元素作为下一个更大值,所以需要遍历两次。
2.此题在上一题上做了优化,因为题目没有给出数值小于10000这样的限制条件,因此直接记录了数组下标值进行比较,毕竟也不需要拿另一个数组进行依次查找。
3.当新元素小于栈顶元素的时候,可以直接入栈,这样形成的栈为单调递增栈。由于要遍历两次,就不可以最后再将栈中元素对应返回-1,会覆盖原值,所以就用memset进行初始赋值。
4.至于为什么memset(res,-1,sizeof(res))会报错,我还没想明白,等一个大佬解答。
C语言代码:
int* nextGreaterElements(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
if (numsSize == 0)
return NULL;
int i, top = -1;
int *res = malloc(sizeof(int) * numsSize);
int *stack = (int*)malloc(sizeof(int) * (2 * numsSize - 1)); //单调栈
memset(res, -1, sizeof(int) * numsSize); //赋初值
//遍历数组,记录每个元素的下一个更大元素
for (i = 0; i < 2 * numsSize - 1; i++)
{
int index = i % numsSize; //循环遍历下标
if (top == -1) //如果为空栈,直接入栈
stack[++top] = index;
else{
while (top >= 0)
{ //只要新元素大于栈顶元素,则出栈且记录进哈希表
if (nums[index] > nums[stack[top]])
res[stack[top--]] = nums[index];
else
break;
}
//不管是弹栈后记录进哈希表,还是可以直接入栈,都需要把新元素入栈
stack[++top] = index;
}
}
//由于本题是扫描两轮,所以会重复入栈,不能直接操作,还是要用memset定义初值
// while (top >= 0) //把栈中剩余元素的哈希表值设为-1
// res[stack[top--]] = -1;
return res;
}