タイトル説明
繰り返し要素のない2つの配列nums1とnums2が与えられます。ここで、nums1はnums2のサブセットです。nums2のnums1の各要素の次に大きい値を見つけます。
nums1の数値xの次に大きい要素は、nums2の対応する位置の右側にあるxより大きい最初の要素を指します。存在しない場合、対応する位置は-1を出力します。
出典:LeetCode
リンク:https://leetcode-cn.com/problems/next-greater-element-i
著作権はLeetCodeが所有しています。商用転載の場合は、公認機関にご連絡ください。非商用転載の場合は、出典を明記してください。
回答
- 公式ソリューションを参照してください
- 一般的な考え方:配列1は配列2のサブセットです。配列2を1回トラバースし、すべての要素の次に大きい要素をハッシュテーブルに格納し、配列1を再度トラバースして、次の要素を配列1の順に変更します。要素が別の配列に読み込まれます。配列2の各要素の次に大きい要素を取得します。現在指している要素をスタックの一番上の要素と比較します。スタックの一番上の要素が現在指している配列2の要素よりも小さい場合は、スタックの一番上の要素と、この時点で指している配列をポップします。2の要素は次に大きい要素であり、スタック内の要素が現在配列2を指している要素より小さくならないまで比較されます。ポインティング要素はスタックにプッシュされ、ポインターは配列2の次の要素を指します。配列2の要素がトラバースされるまで、このようにループします。トラバースされると、スタックの残りの要素に次に大きな要素がなくなります。
- C言語の実装
#define maxsize 1000
typedef struct
{
char write;//有无写入数据标记
int key,nextmax;//键值,下一个更大元素
}hashmap;
hashmap* inithashmap(void)//建立并初始化哈希表
{
hashmap* hash=(hashmap *)malloc(maxsize*sizeof(hashmap));
for(int i=0;i<maxsize;i++)
hash[i].write=0;
return hash;
}
void writehash(hashmap* h,int key,int nextmax)//写入新的哈希表项
{
int p=key%maxsize;
while(h[p].write!=0)
{
p=(p+1)%maxsize;//使用线性探测法解决冲突
}
h[p].write=1;
h[p].key=key;
h[p].nextmax=nextmax;
return;
}
int readhash(hashmap* h,int key)//读取对应键值的哈希表值
{
int p=key%maxsize;
while(h[p].key!=key)
{
p=(p+1)%maxsize;
}
return h[p].nextmax;
}
void destroy(hashmap* h)
{
free(h);
}
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
*returnSize=nums1Size;
int* r_array=(int *)malloc((*returnSize)*sizeof(int));
hashmap* hm=inithashmap();//哈希表
int* stack=(int *)malloc(nums2Size*sizeof(int));//栈
int top=-1;//栈指针
for(int i=0;i<nums2Size;i++)
{
while(top>-1&&stack[top]<nums2[i])//小于当前比较值则出栈,当前值即为栈顶元素下一个更大元素
{
writehash(hm,stack[top--],nums2[i]);//放入哈希表
}
stack[++top]=nums2[i];//当前值入栈
}
//将剩余的元素写入哈希表,剩余元素没有下一个更大元素
while(top>-1)
{
writehash(hm,stack[top--],-1);
}
//读取哈希表的值如数组
for(int i=0;i<nums1Size;i++)
{
r_array[i]=readhash(hm,nums1[i]);
}
free(stack);
destroy(hm);
return r_array;
}