leetcode 周赛214 学习笔记(5561、1647)

5561. 获取生成数组中的最大值

问题描述:传送门

思路:

1、vector容器规划大小,通过与运算判断奇偶,递归,最后利用max函数求最值。

代码:

class Solution {
public:
    int getMaximumGenerated(int n) {
        vector<int> v;
        v.resize(105);//根据题意,重新规划一下容器大小
        v[0]=0;v[1]=1;//题意
        for(int i=2;i<=n;i++){
            if(i&1){
                 v[i]=v[i/2]+v[(i/2)+1];
            }else{
            v[i]=v[i/2];    
            }
        }
        int ans=-1;
        for(int i=0;i<=n;i++){
            ans=max(ans,v[i]);
        }
    return ans;
    }
};

1647. 字符频次唯一的最小删除次数

问题描述:传送门

思路:

1、贪心算法+两个map

代码:

class Solution {
class Solution {
public:
    int minDeletions(string s) {
      map<char,int> cnt;//先把每个字母的频数记录一下,example:  abbccddd
      for(int i=0;i<s.size();i++){
          cnt[s[i]]++;//遇到这个字符,频数就++
      }
      map<int,int> r;
      for(auto j:cnt){
          //j.first统计每个字母,有多少频次,如a=1、bb=2、cc=2,ddd=3;
          //j.second,有多少个不同字母,符合这个次数,bbcc=2
          r[j.second]++;//两个不同字母频数相同的+1,r[2]=2;
      }
        int ans =0;//统计删除的次数
        int now=0;//扫数的时候,记录一下当前位置
    while(r.size()>0){
        //先保证频次不为null
        if(r.rbegin()->second==1){
            //频次为1,优先出图,如d[3]==1
            now = r.rbegin()->first;
            r.erase(r.find(now));//把当前位置,移出去
        }else{
           //now代表频次,r[now]代表的是相应频次的,不同字母,数量
            now =r.rbegin()->first;
            //形如bb,cc的数,频次now为2,两个频次为2的不同字母,r[2]=2
            r[now]--;//假如去掉一个字母c,r[2]==1,即bbc
            if(now!=1){
                //c侵占了字母a的 r[1]=1;所以r[1]++=2;
                 r[now-1]++;
                }
            //直到当前位置频数只剩1时,ans才不用++。如去掉c,只剩a的时候,r[1]=1;
            ans++;   
            }
        }
      return ans;
    }
};

2、贪心算法+类似双指针
①先开vector统计每个字母,频数
②频数从大到小排序
③设置当前prt,指向cnt【0】。因为前面从大到小排列了,所以只统计整个字符串里从它往后比他大于等于的数
每次循环时,目前能保留的最大值max给ptr,那么ptr后面的字母,要删除的数,就只能是cnt[i]-ptr。
⑤如果后面的字母都比ptr的频数小,那就让ptr往后面走

参考文献

代码:

class Solution {
public:
    int minDeletions(string s) {
       vector<int> cnt(26,0);//统计每个字符出现的次数
       for(auto ch:s){
           cnt[ch-'a']++;//统计频次
       }
       sort(cnt.begin(),cnt.end(),greater<int>());//从大到小排列

       int ptr =cnt[0];
       int ans=0;
       for(int i=1;i<cnt.size()&&cnt[i]>0;i++){
           //零个数最好不计算进去
           if(ptr<=cnt[i]){
               ptr=max(ptr-1,0);//排序到目前,能保留的最大数
               ans+=cnt[i]-ptr;
           }else if(ptr>cnt[i]){
               ptr=cnt[i];//让当前数进位
           }
       }
       return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晓梦林

都看到这里了,支持一下作者呗~

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

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

打赏作者

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

抵扣说明:

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

余额充值