贪心算法总结(3)

一、最长回文串

409. 最长回文串 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    int longestPalindrome(string s) {
          int hash[127]={0};
          for(char&ch:s) ++hash[ch];
          int ret=0;
          for(int&x:hash)  ret+=x/2*2; //技巧1 利用向下取整
          return ret<s.size()?ret+1:ret;
    }
};

二、增减字符串匹配

942. 增减字符串匹配 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    vector<int> diStringMatch(string s) {
       //如果是升 就把最小的放进去  如果是降 就把最大的放进去
       int left=0,right=s.size();
       vector<int> ret;
       ret.reserve(s.size()+1);
       for(auto&ch:s) 
         if(ch=='I') ret.emplace_back(left++);
         else ret.emplace_back(right--);
       ret.emplace_back(left);
       return ret;
    }
};

三、重构字符串

767. 重构字符串 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    string reorganizeString(string s) {
          int hash[26]={0};
          int n=s.size(),maxcount=0,maxchar=' ';
          for(auto&ch:s)
           if(maxcount<++hash[ch-'a']) maxcount=hash[ch-'a'],maxchar=ch;
           //先处理最多的那个
           if(maxcount>(n+1)/2) return "";
           string ret(n,' ');
           int index=0;
           for(int i=0;i<maxcount;++i)
           {
              ret[index]=maxchar;
              index+=2;
           }
           hash[maxchar-'a']=0;
           for(int i=0;i<26;++i)
            for(int j=0;j<hash[i];++j)
             {
                if(index>=n) index=1;
                ret[index]='a'+i;
                index+=2;
             }
             return ret;
    }
};

四、最优除法

553. 最优除法 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    string optimalDivision(vector<int>& nums) {
       int n=nums.size();
       if(n==1) return to_string(nums[0]);
       if(n==2) return to_string(nums[0])+"/"+to_string(nums[1]);
        string ret=to_string(nums[0])+"/("+to_string(nums[1]);
        for(int i=2;i<n;++i) ret+="/"+to_string(nums[i]);
        ret+=")";
       return ret;
    }
};

五、单调递增的数字

738. 单调递增的数字 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
//要获取一个数的数位关系的时候 一般有两个技巧,第一个是变成字符串 第二个就是/10 %10
    int monotoneIncreasingDigits(int n) {
       //根据贪心策略,首先第一步我们要找到第一个下降的数,然后让他-1 之后再把后面所有的数都变成9
       //但是比如12345555123这种情况。就需要进行回退 回退到第一个5的位置然后再进行上面的操作
       string s=to_string(n);
       int m=s.size(),i=0;
       while(i+1<n&&s[i]<=s[i+1]) ++i; //找到第一个下降趋势的
       if(i==m-1) return n;//可能直接走到头了
       //如果没有走到头,开始回退
       while(i-1>=0&&s[i]==s[i-1]) --i;
       --s[i];
       //然后让后面的位置变成9
       for(int j=i+1;j<m;++j) s[j]='9';
       return stoi(s);
    }
};

六、坏了的计算机

991. 坏了的计算器 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    int brokenCalc(int startValue, int target) {
        int ret=0;
      while(target>startValue) 
      {
        if(target%2) ++target;
        else target/=2;
        ++ret;
      } 
      return ret+startValue-target;
    }
};

七、整数替换

397. 整数替换 - 力扣(LeetCode)

解法1:递归+记忆化搜索

cpp 复制代码
class Solution {
public:
    unordered_map<int,int> hash;
    int integerReplacement(int n) {
       return dfs(n);
    }
    int dfs(long n) //细节问题 容易溢出
    {
          //模拟 递归 记忆化搜索 
        if(hash.count(n)) return hash[n];
        if(n==1) return hash[1]=0;
        else if(n%2)  return hash[n]=1+min(dfs(n-1),dfs(n+1));
        else  return hash[n]=dfs(n/2)+1;
    }
};

解法2:贪心

cpp 复制代码
class Solution {
public:
    int integerReplacement(int n) {
        int ret=0;
       while(n>1)
       {
        if(n%2==0) n/=2,++ret;
        else
        {
            if(n==3) n=1;
            else if(n%4==1)  n/=2;
            else n=n/2+1;
            ret+=2;
        }
       }
       return ret;
    }
};

八、可被三数整除的最大和

1262. 可被三整除的最大和 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    int maxSumDivThree(vector<int>& nums) {
        // 正难则反
        //sum%3==0  
        //sum%3==1     x1  或者y1y2
        //sum%3==2     x1x2或者y1
        const int INF=0x3f3f3f3f;
        int sum=0,x1=INF,x2=INF,y1=INF,y2=INF;
        for(auto&e:nums)
        {
           sum+=e;
           if(e%3==1) 
           {
             if(e<x1) x2=x1,x1=e;
             else if(e<x2) x2=e;
           }
           else if(e%3==2)
           {
             if(e<y1) y2=y1,y1=e;
             else if(e<y2) y2=e;
           }
        }
        if(sum%3==0) return sum;
        else if(sum%3==1) return max(sum-x1,sum-y1-y2);
        else return max(sum-x1-x2,sum-y1);
    }
};
相关推荐
-Max-静-几秒前
Paddle Inference部署推理(十八)
人工智能·windows·深度学习·算法·paddle·推理 部署
qq_485668991 小时前
算法习题--蓝桥杯
算法·职场和发展·蓝桥杯
waves浪游1 小时前
类和对象(中)
c语言·开发语言·数据结构·c++·算法·链表
做人不要太理性1 小时前
【算法一周目】滑动窗口(2)
c++·算法·leetcode·哈希算法·散列表·滑动窗口
青い月の魔女1 小时前
数据结构初阶---复杂度
c语言·数据结构·笔记·学习·算法
汤姆和杰瑞在瑞士吃糯米粑粑1 小时前
【优先算法学习】双指针--结合题目讲解学习
c++·学习·算法
m0_547486661 小时前
数据结构试题库1
java·数据结构·算法
多多*1 小时前
后端并发编程操作简述 Java高并发程序设计 六类并发容器 七种线程池 四种阻塞队列
java·开发语言·前端·数据结构·算法·状态模式
摆烂小白敲代码1 小时前
【算法】连通块问题(C/C++)
c语言·数据结构·c++·算法·深度优先·图论·广度优先
香菜大丸1 小时前
详解 指针函数,函数指针,函数指针函数
开发语言·c++·算法