leetcode496、下一个更大元素I
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。
给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。
示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
示例 2:
输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
*returnSize=nums1Size;
int* ans=(int*)malloc(sizeof(int)*nums1Size);
int* stack=(int*)malloc(sizeof(int)*nums2Size);
int top=-1;
stack[++top]=0;//栈中存储元素下标
for(int i=0;i<nums1Size;i++){
ans[i]=-1;
}
for(int i=1;i<nums2Size;i++){//遍历数组2
if(nums2[i]<=nums2[stack[top]])
stack[++top]=i;//入栈
else{
while(top!=-1&&nums2[i]>nums2[stack[top]]){
for(int j=0;j<nums1Size;j++){
if(nums2[stack[top]]==nums1[j])//找到栈顶元素在数组1中对应的下标
ans[j]=nums2[i];//找到栈顶元素的下一个更大元素
}
--top;//栈顶元素出栈
}
stack[++top]=i;//将当前元素入栈
}
}
return ans;
}
leetcode503、下一个更大元素II
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
示例 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
示例 2:
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
int* nextGreaterElements(int* nums, int numsSize, int* returnSize) {
*returnSize=numsSize;
int* ans=(int*)malloc(sizeof(int)*numsSize);
int* stack=(int*)malloc(sizeof(int)*numsSize*2);
int top=-1;
for(int i=0;i<numsSize;i++)
ans[i]=-1;
for(int i=0;i<numsSize*2;i++){
while(top!=-1&&nums[i%numsSize]>nums[stack[top]]){
ans[stack[top]]=nums[i%numsSize];//找到当前元素下一个比它更大的数
--top;//栈顶元素出栈
}
stack[++top]=i%numsSize;//当前元素下标入栈
}
return ans;
}
华为od机试(C卷,100分)- 转盘寿司
题目描述
寿司店周年庆,正在举办优惠活动回馈新老客户。
寿司转盘上总共有 n 盘寿司,prices[i] 是第 i 盘寿司的价格,
如果客户选择了第 i 盘寿司,寿司店免费赠送客户距离第 i 盘寿司最近的下一盘寿司 j,前提是 prices[j] < prices[i],如果没有满足条件的 j,则不赠送寿司。
每个价格的寿司都可无限供应。
输入描述
输入的每一个数字代表每盘寿司的价格,每盘寿司的价格之间使用空格分隔,例如:
3 15 6 14
表示:
第 0 盘寿司价格 prices[0] 为 3
第 1 盘寿司价格 prices[1] 为 15
第 2 盘寿司价格 prices[2] 为 6
第 3 盘寿司价格 prices[3] 为 14
寿司的盘数 n 范围为:1 ≤ n ≤ 500
每盘寿司的价格 price 范围为:1 ≤ price ≤ 1000
输出描述
输出享受优惠后的一组数据,每个值表示客户选择第 i 盘寿司时实际得到的寿司的总价格。使用空格进行分隔,例如:
3 21 9 17
用例
输入 3 15 6 14
输出 3 21 9 17
说明 无
题目解析
本题其实就是要我们求解数组中每个元素的下一个更小值元素,另外数组是循环的,即:如果数组某个元素之后没有比其更小的,那么可以循环到数组头部继续找。
本题其实就是LeetCode - 503 下一个更大元素的变种题。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int price[500];
int num=0;
while(scanf("%d",&price[num++])){
if(getchar()!=' ')break;
}
int stack[num*2];
int top=-1;
int ans[num];
for(int i=0;i<num;i++)
ans[i]=price[i];
for(int i=0;i<num*2;i++){
while(top!=-1&&price[i%num]<price[stack[top]]){//当前元素价格下于栈顶元素,找到栈顶元素的下一个最小值
//printf("%d",ans[stack[top]]);
ans[stack[top]]=price[i%num]+price[stack[top]];
top--;//栈顶元素出栈
}
stack[++top]=i%num;//当前元素入栈
}
printf("\n");
for(int i=0;i<num;i++)
printf("%d ",ans[i]);
return 0;
}