Leetcode第209题长度最小的子数组||C语言

方法一:暴力法,将子数组元素数量num初始化为数组元素+1,用双指针进行遍历,i指针从头到尾遍历数组,每次遍历一个i元素,则从i+1的位置开始移动j指针,直至从i到j的元素之和大于target,再判断元素数量是否小于num,若小于则将其赋给num。但执行之后超时

int minSubArrayLen(int target, int* nums, int numsSize){
  int i=0;
  int j;
  int num=numsSize+1;
  int temp_sum;
  int temp_num=0;
  while(i<numsSize){
      if(nums[i]>=target){
          num=1;
          break;
      }
      j=i+1;
      temp_sum=nums[i];
      while(j<numsSize){
          temp_sum+=nums[j];
          if(temp_sum<target) j++;
          else{
              temp_num=j-i+1;
              if(temp_num<num) num=temp_num;
              break;
          }
      }
      i++;
  }
  if(num>numsSize)return 0;
  else return num;
}

执行情况
方法二:双指针法,跟一类似,将子数组元素数量num初始化为数组元素+1,用双指针进行遍历。
但第二层while循环我用了一系列if语句代替,使得每次执行到最外层while的时候不需要让j重新回溯到i+1的位置,而是令i+1
(话说我想起了当时学408时的next数组,感觉上好像这么说起来挺相似的,不过当时没具体去研究代码哈哈)
按以下思考的顺序结合代码可能比较好理解:
第一步:如果有一个数大于或等于target,就不用执行剩余语句了,直接break后返回1
第二步:将当轮j的元素加入temp_sum中,并让j移到下一位元素
第三步:判断上一轮循环形成的temp_sum是否大于或等于target,如是则接着判断temp_num(即i和j之间的元素数量)是否小于num,如是则更新num的值,同时如果i小于j,则将temp_sum减去i对应的元素,并将i指针移到下一元素,此时的temp_sum即为新i到j之间元素的和
第四步:由于子数组元素数量num在最开始初始化为数组元素+1,所以进行判断,如果num>numsSize(其实就是判断num==numsSize,写成这样也一样),说明整个数组加起来不够target,故返回0,否则直接返回num

注意:每轮的i到j区间为左闭右开,因为j是将自身的值加到temp_sum后进行的自增,新j的值并没有在当轮加到temp_sum之中,而是等到下一轮进行判断之后才加进去,因此求temp_num(即i和j之间的元素数量)时不用“j-i+1”,直接“j-i”即可

int minSubArrayLen(int target, int* nums, int numsSize){
  int i=0;
  int j=i+1;
  int num=numsSize+1;
  int temp_sum=nums[i];
  int temp_num=0;
  while(i<numsSize){
  //以下为第一步
      if(nums[i]>=target){
          num=1;
          break;
      }
    //以下为第三步
      else if(temp_sum>=target){
          temp_num=j-i;
          if(temp_num<num) num=temp_num;
          if(i<j){
              temp_sum-=nums[i];
              i++;
          } 
      }
//以下为第二步
      else if(j<numsSize){
        temp_sum+=nums[j];
        j++;
      }
     else{
         break;
     } 
  }
//以下为第四步
  if(num>numsSize)
      return 0;
  else
      return num;
}

执行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值