1.13学習ブログ

今日は、スタックに関連する2つのトピックを要約します。
最初の質問:毎日の気温。
ここに画像の説明を挿入
このトピックでは、力ずくのトラバーサルを使用するとタイムアウトになるため、スタックを使用して問題を解決します。

for 循环要从后往前扫描元素,倒着入栈,正着出栈。
while 循环是把两个较大元素之间的元素排除
部分代码:
int* dailyTemperatures(int* T, int TSize, int* returnSize){
    
    
*returnSize = TSize;
    int *ans = malloc(sizeof(int)*TSize);
    int stack[TSize+1];  //栈底不放元素,因此要多一个空间
    int top = 0;
    for(int i = TSize-1; i >= 0; i--)  //for 循环要从后往前扫描元素{
    
    
        while(top != 0 && T[stack[top]] <= T[i])//如果在栈中找不到比T[i]大的元素,则栈减,直至找到比T[i]大的元素或者top为0
         top--;
        ans[i] = top==0 ? 0 : (stack[top] - i);//利用下标得到索引间距,若top=0,说明栈中(即该元素后)没有比当前元素大的。
        stack[++top] = i;  //将下标放入栈
    }
    return ans;
}

質問2:次の大きな要素II
ここに画像の説明を挿入
公式ソリューションの助けを借りて、単調スタック使用してこの問題を解決できます

最初に最初の要素A [1]をスタックに配置し、次に2番目の要素A [2]について、A [2]> A [1]の場合、A [1]の次の更新を見つけます。大きな要素A [2]、この時点で、A [1]をスタックからポップして、A [2]をスタックにプッシュできます。A[2] <= A [1]の場合、A [2]のみをスタックにプッシュします。スタック。3番目の要素A [3]の場合、この時点でスタックにいくつかの要素があり、A [3]より小さいすべての要素が次に大きい要素(つまりA [3])を見つけたので、それらをからポップできます。スタック。その後、A [3]をスタックにプッシュします。

単調なスタックを維持しており、スタック内の要素はスタックの上部から下部まで単調であることがわかります。新しい要素A [i]に遭遇すると、スタックの一番上の要素がA [i]よりも小さいかどうかを判断します。小さい場合、スタックの一番上にある次に大きい要素はA [i]です。 、そして私たちはします要素はスタックからポップされます。スタックが空になるか、スタックの最上位要素がA [i]より大きくなるまで、この操作を繰り返します。このとき、A [i]をスタックにプッシュし、スタックを単調に保ち、次のA [i + 1]、A [i +2]…に対して同じ操作を実行します。

この質問の配列はループ配列であるため、各要素をスタックに2回プッシュする必要があります。このようにして、一部の要素がスタックから一度ポップアウトされる可能性があります。つまり、複数の「次に大きい要素」が取得され、最初のポップアップの結果を保持するだけで済みます。

int* nextGreaterElements(int* nums, int numsSize, int* returnSize){
    
    
if(numsSize==1){
    
    nums[0]=-1;*returnSize=1;return nums;}//个数为1的特殊情况
if(numsSize==0){
    
    *returnSize=0;return nums;}//个数为0的特殊情况
int*stack=(int*)malloc(sizeof(int)*(numsSize*2+1));//我们要保证每个元素入栈2次
int*ans=(int*)malloc(sizeof(int)*numsSize);
memset(ans,-1,sizeof(ans));
memset(stack,-1,sizeof(stack));
int top=-1,x=numsSize-1;
for(int i=numsSize-1;i>=0;i--){
    
    //第一次从后向前遍历
    while(top!=-1&&stack[top]<nums[i])top--;
    if(top==-1){
    
    
        stack[++top]=nums[i];
        ans[i]=-1;
    }
    else{
    
    
        ans[i]=stack[top];
        stack[++top]=nums[i];
    }
}
for(int i=numsSize-1;i>=0;i--){
    
    //第二次从后向前遍历
    while(top!=-1&&stack[top]<=nums[i])top--;
    if(top==-1){
    
    
        stack[++top]=nums[i];
        ans[i]=-1;
    }
    else{
    
    
        ans[i]=stack[top];
        stack[++top]=nums[i];
    }
}
*returnSize=numsSize;
free(stack);
return ans;
}

おすすめ

転載: blog.csdn.net/weixin_47529865/article/details/112583057