【贪心算法】(第七篇)

目录

最⻓回⽂串(easy)

题目解析

讲解算法原理

编写代码

增减字符串匹配(easy)

题目解析

讲解算法原理

编写代码


最⻓回⽂串(easy)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定⼀个包含⼤写字⺟和⼩写字⺟的字符串 s ,返回通过这些字⺟构造成的最⻓的回⽂串。在构造过程中,请注意区分⼤⼩写。⽐如 "Aa" 不能当做⼀个回⽂字符串。

⽰例1:

输⼊:s="abccccdd"

输出:7

解释:

我们可以构造的最⻓的回⽂串是"dccaccd",它的⻓度是7。⽰例2:

输⼊:s="a"

输出:1

⽰例3:

输⼊:s="aaaaaccc"

输出:7

提⽰:

◦ 1 <= s.length <= 2000

◦ s 只由⼩写和/或⼤写英⽂字⺟组成

讲解算法原理

解法(贪⼼):
贪⼼策略:

⽤尽可能多的字符去构造回⽂串:

a. 如果字符出现偶数个,那么全部都可以⽤来构造回⽂串;b. 如果字符出现奇数个,减去⼀个之后,剩下的字符能够全部⽤来构造回⽂串;c. 最后再判断⼀下,如果有字符出现奇数个,就把它单独拿出来放在中间。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
public:
 int longestPalindrome(string s) 
 {
 // 1. 计数 - ⽤数组模拟哈希表
 int hash[127] = { 0 };
 for(char ch : s) hash[ch]++;
 // 2. 统计结果
 int ret = 0;
 for(int x : hash)
 {
 ret += x / 2 * 2;
 }
 return ret < s.size() ? ret + 1 : ret;
 }
};

java算法代码:

java 复制代码
class Solution
{
 public int longestPalindrome(String s) 
 {
 // 1. 计数 - ⽤数组模拟哈希表
 int[] hash = new int[127];
 for(int i = 0; i < s.length(); i++)
 {
 hash[s.charAt(i)]++;
 }
 // 2. 统计结果
 int ret = 0;
 for(int x : hash)
 {
 ret += x / 2 * 2;
 }
 return ret < s.length() ? ret + 1 : ret;
 }
}

增减字符串匹配(easy)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表⽰为⻓度为 n 的字符串 s ,其中:

• 如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I'

• 如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D'

给定⼀个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中任何⼀个。

⽰例1:

输⼊:s="IDID"

输出:[0,4,1,3,2]

⽰例2:

输⼊:s="III"

输出:[0,1,2,3]

⽰例3:

输⼊:s="DDI"

输出:[3,2,0,1]

提⽰:

◦ 1 <= s.length <= 10(5)

◦ s 只包含字符 "I" 或 "D"

讲解算法原理

解法(贪⼼):
贪⼼策略:

a. 当遇到 'I' 的时候,为了让下⼀个上升的数可选择的「范围更多」,当前选择「最⼩」的那

个数;

b. 当遇到 'D' 的时候,为了让下⼀个下降的数可选择的「范围更多」,选择当前「最⼤」的那

个数。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
public:
 vector<int> diStringMatch(string s) 
 {
 int left = 0, right = s.size(); // ⽤ left,right 标记最⼩值和最⼤值 vector<int> ret;
 for(auto ch : s)
 {
 if(ch == 'I') ret.push_back(left++);
 else ret.push_back(right--);
 }
 ret.push_back(left); // 把最后⼀个数放进去
 return ret;
 }
};

java算法代码:

java 复制代码
class Solution
{
 public int[] diStringMatch(String s) 
 {
 int n = s.length();
 int left = 0, right = n; // ⽤ left,right 标记最⼩值和最⼤值 int[] ret = new int[n + 1];
 for(int i = 0; i < n; i++)
 {
 if(s.charAt(i) == 'I')
 {
 ret[i] = left++;
 }
 else
 {
 ret[i] = right--;
 }
 }
 ret[n] = left; // 把最后⼀个数放进去
 return ret;
 }
}
相关推荐
半盏茶香8 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
是梦终空9 分钟前
JAVA毕业设计210—基于Java+Springboot+vue3的中国历史文化街区管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·历史文化街区管理·景区管理
哎呦,帅小伙哦15 分钟前
Effective C++ 规则41:了解隐式接口和编译期多态
c++·effective c++
CodeJourney.27 分钟前
小型分布式发电项目优化设计方案
算法
基哥的奋斗历程33 分钟前
学到一些小知识关于Maven 与 logback 与 jpa 日志
java·数据库·maven
m0_5127446434 分钟前
springboot使用logback自定义日志
java·spring boot·logback
十二同学啊38 分钟前
JSqlParser:Java SQL 解析利器
java·开发语言·sql
老马啸西风1 小时前
Plotly 函数图像绘制
java
DARLING Zero two♡1 小时前
【初阶数据结构】逆流的回环链桥:双链表
c语言·数据结构·c++·链表·双链表
9毫米的幻想1 小时前
【Linux系统】—— 编译器 gcc/g++ 的使用
linux·运维·服务器·c语言·c++