【leetcode】239/剑指offer59_滑动窗口的最大值_C语言代码+注释

滑动窗口的最大值

题目
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释: 

  滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7


提示:

1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
1 <= k <= nums.length

分析

思路:

1.首先找出数组中最前面k个元素的最大值,放在返回数组ret[0]中。
2.之后每往后滑动时,先判断滑走的元素是否为最大值,

2.1若最大值仍然在窗口中,判断最大值和滑入窗口的元素的值,取较大者。

2.2 若最大值滑走,则在新窗口元素中重新找最大值。

进一步分析:

  1. 第一步中找最大值的操作和2.2中相同,可以用函数模块化,此函数的参数应该为int Max(int* num,int left,int right)即数组名,开始的下标,结束的下标。
    2.整个题目要求返回一个max数组和确定此数组的大小int* returnSize

细节实现:

1.首先要判断传入参数的合法性!如果传入数组为NULL则类似nums[i]的操作都是非法的,所以一定要先判断if(numsSize==0)再进一步行动!
2.其次,确定此数组的大小int* returnSize,由窗口滑动的特性我们可以发现*returnSize=numsSize+1-k;
3.在窗口滑动时,要注意最后一个元素为特殊边界,在下面代码中,我加入了这一段来防止溢出

if(i+k==numsSize)
          break;

下面是完整代码:

int Max(int* num,int left,int right)
{
    int max=num[left];
    for(int i=left;i<=right;i++)
     {
         if(max<num[i])
           max=num[i];
     }
     return max;
}

int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize)
{
    if(numsSize==0)
    {
        *returnSize=0;
        return NULL;
    }
    int *ret;
    ret = (int *)malloc(sizeof(int)*(numsSize-k+1));
   
    int i,j;
    ret[0] = Max(nums,0,k-1);
    int max;
    max=ret[0];
    
    for(i=0;i<(numsSize+1-k);i++)
    {
        ret[i] = max;
        if(i+k==numsSize)
          break;
        if(ret[i]>nums[i])//最大值没有出队
          {
              if(ret[i]<nums[i+k])//且新入队元素比最大值大
                 max=nums[i+k];                
          }
         /*
         上面两个嵌套的if循环不可以改成
         if(ret[i]>nums[i]&&(ret[i]<nums[i+k]))//最大值没有出队且新入队元素比最大值大
         因为下面的else语句是否则的最大值没有出队的情况
         */
        else
        {       
            max = Max(nums,i+1,i+k);
        }
    }
    *returnSize=numsSize+1-k;
   return ret;
}

最后附上自己用于测试的main函数

int main()
{
    int nums[]={-2,5,8,-9,3,0,45,-90};
    int a=1;


    int *arr=maxSlidingWindow(nums, 8, 3,&a);
    //printf("a=%d\n",a);
    for(int i=0;i<a;i++)
    {
        printf("%d\n",arr[i]);
    }
    
   return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值