力扣2856.删除数对后的最小数组长度

力扣2856.删除数对后的最小数组长度

朴素做法

  • 观察到只要不一样的数就一定可以删

  • 找到出现次数最多的那个数字的次数

    • 1.出现次数超过半数,即max*2 >= n
      • 一定有其他数全都可以与max的数抵消 剩余max*2 - n个
    • 2.出现次数不超过半数,即max*2 < n
      • 其他的数可证明一定可以抵消到<max个之后再与max抵消
      • 所以结果为n%2
  •   class Solution {
      public:
          int minLengthAfterRemovals(vector<int>& nums) {
              int n = nums.size(),m=0;
              unordered_map<int,int> cnt;
              for(auto t:nums)
              {
                  cnt[t] ++;
                  m = max(cnt[t],m);
              }
          cout<<m<<endl;
          return max(m*2-n,n%2);
          }
      };
    

优化

  • 因为数组有序,所以超过半数的元素一定会在n/2的位置(中位数)

    • 所以二分求出nums[n/2]的数量
    • 然后直接return max(max_d*2 - n , n%2);
  •   class Solution {
      public:
          int minLengthAfterRemovals(vector<int>& nums) {
              int n = nums.size();
              int x = nums[n/2];
              int sum = ranges::upper_bound(nums,x) - ranges::lower_bound(nums,x);
              return max(sum * 2 - n, n % 2);
          }
      };
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值