力扣:239. 滑动窗口最大值 347. 前 K 个高频元素

239. 滑动窗口最大值:

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

返回 滑动窗口中的最大值 

思路1:暴力解法——超时;每滑动一次就找窗口中找到最大值,时间复杂度是O(n*k);具体代码实现如下:

var maxSlidingWindow = function(nums, k) {
  let left = 0;
  let right = k-1;
  let maxNums = [];
  for(right; right < nums.length;){
      let temp = left;
      let max = nums[left];
      while(temp<=right){
          max = Math.max(max,nums[temp])
          temp++
      }
      maxNums.push(max);
      left++;
      right++;
  }
  return maxNums
};

既然超时了,就需要分析怎么优化;上面代码中的while循环是是比了所有数,能不能减少比较的次数;情况1如果上一次在窗口中的数最大的值是中间的(非两端),是不是就可以直接用这个结果和下一次最右边的数对比就好了;情况2如果上一次在窗口中的最大数就是最左边的,这一次就不能利用上一次max的结果了,就只能保持原来的逻辑遍历所有的找最大值;具体代码实现如下:

var maxSlidingWindow = function(nums, k) {
  if(k === 1){ // 如果窗口宽度是1就返回原数组;
      return nums;
  }
  let left = 0; // 窗口左下标
  let right = k-1; // 窗口右下标
  let maxNums = []; // 放最大值的结果
  let temp = left; // 将左边值赋给临时变量用于找最大值;
  let max = nums[left]; // 单个窗口中的最大值;
  let maxIndex = 0;  // 单个窗口中的最大值的下标;
  while(temp<=right){ // 找到第一个窗口中的最大值;
      if(nums[temp]>=max){
          max = nums[temp];
          maxIndex = temp; // 更新最大值的下标
      }
      temp++
  }
  maxNums.push(max);
  left++;
  right++;
  for(right; right < nums.length;){
      if(left <= maxIndex){ // 最大值在上一次的非最左边
          // 只需要比较上次最大值和最右边的值
          if(max<nums[right]){
            max = nums[right];
            maxIndex = right;
          }
      } else { // 最大值在最左边
          let temp1 = left;
          max = nums[left];
          while(temp1<=right){
              if(nums[temp1]>=max){
                  max = nums[temp1];
                  maxIndex = temp1;
              }
              temp1++
          }
      }
      maxNums.push(max);
      left++;
      right++;
  }
  return maxNums
};

优化之后可以通过,但是并非最优解;该题还可以尝试使用队列的思路,使用队列维护窗口中的递减队列,本次就不分享了后续再分享;

347. 前 K 个高频元素:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

思路:将所有nums通过map统计出数字出现的频率,把所有的数据都排序一遍之后取前k个元素,返回即可;具体代码实现如下:

var topKFrequent = function(nums, k) {
  let map = new Map();
  let result = [];
  for(item of nums){
      if(map.has(item)){
          map.set(item,map.get(item)+1)
      } else {
          map.set(item,1)
      }
  }
  for(item of map){
      result.push({item:item[0],val:item[1]})
  }
  result.sort((a,b)=> b.val-a.val)
  result.splice(k);
  return result.map(item=>item.item)
};

今天的分享就到这里了,谢谢;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值