【字符串】【贪心】【 树状数组】2193. 得到回文串的最少操作次数

作者推荐

视频算法专题

本文涉及知识点

字符串 贪心 树状数组 分类讨论

LeetCode2193. 得到回文串的最少操作次数

给你一个只包含小写英文字母的字符串 s 。
每一次 操作 ,你可以选择 s 中两个 相邻 的字符,并将它们交换。
请你返回将 s 变成回文串的 最少操作次数 。
注意 ,输入数据会确保 s 一定能变成一个回文串。
示例 1:
输入:s = “aabb”
输出:2
解释:
我们可以将 s 变成 2 个回文串,“abba” 和 “baab” 。

  • 我们可以通过 2 次操作得到 “abba” :“aabb” -> “abab” -> “abba” 。
  • 我们可以通过 2 次操作得到 “baab” :“aabb” -> “abab” -> “baab” 。
    因此,得到回文串的最少总操作次数为 2 。
    示例 2:
    输入:s = “letelt”
    输出:2
    解释:
    通过 2 次操作从 s 能得到回文串 “lettel” 。
    其中一种方法是:“letelt” -> “letetl” -> “lettel” 。
    其他回文串比方说 “tleelt” 也可以通过 2 次操作得到。
    可以证明少于 2 次操作,无法得到回文串。
    提示:
    1 <= s.length <= 2000
    s 只包含小写英文字母。
    s 可以通过有限次操作得到一个回文串。

贪心

s[0]和s[n-1]是第0对,s[1]和s[n-2]是第二对…
从大到小处理第i对,会让已经处理好的对,不在匹配。故只能从小到大处理。

分类讨论

任意两对x和y,有如下关系:
一,xxyy,两者相互无影响。
二, ⋯ a 个字符 x ⋯ b 个字符 y ⋯ c 个字符 y ⋯ d 个字符 x ⋯ e 个字符 ^{a个字符}_{\cdots} x ^{b个字符}_{\cdots}y ^{c个字符}_{\cdots}y ^{d个字符}_{\cdots}x ^{e个字符}_{\cdots} a个字符xb个字符yc个字符yd个字符xe个字符
先处理x,需要:a+e 在处理y,需要:a+b+d+e
先处理y:需要a+b+1+d+e+1,再处理x需要:a+e。
必须先处理x。
三, ⋯ a 个字符 x ⋯ b 个字符 y ⋯ c 个字符 x ⋯ d 个字符 y ⋯ e 个字符 ^{a个字符}_{\cdots} x ^{b个字符}_{\cdots}y ^{c个字符}_{\cdots}x ^{d个字符}_{\cdots}y ^{e个字符}_{\cdots} a个字符xb个字符yc个字符xd个字符ye个字符
先处理x: a+d+e+1,再处理y: a+b+e
线处理y: a+b+1+e 再处理x:a+d+e
结果一样:先处理谁都可以。
结果: 除非被另外一个字符包括,则可以先处理。
最左边的x,如果有多个可以匹配的x,选择最右边的x。
F o r i : 0 i < s . l e n g t h / 2 匹配 s [ i ] For\Large_{i:0}^{i < s.length/2}匹配s[i] Fori:0i<s.length/2匹配s[i]
如果s[i] 是只有一个,按就是中心。从后面处理,将s转置。
以可以忽略,留到最后处理:

	if (0 == index)
			{
				iRet += s.length()/2;
                s = s.substr(1);
				continue;
			}

代码

核心代码

class Solution {
public:
	int minMovesToMakePalindrome(string s) {
		int iRet = 0;
		while (s.length() > 2)
		{
			int index = s.find_last_of(s[0]);
			if (0 == index)
			{
				std::reverse(s.begin(), s.end());
				continue;
			}
			iRet += (s.length() - 1 - index);
			s = s.substr(1, index - 1) + s.substr(index + 1);
		}
		return iRet;
	}
};

测试用例

template<class T,class T2>
void Assert(const T& t1, const T2& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}

}

int main()
{
	string s ;
	{
		Solution sln;
		s = "adabb";
		auto res = sln.minMovesToMakePalindrome(s);
		Assert(3, res);
	}
	
	
}

2023 年 3月版

class Solution {
public:
int minMovesToMakePalindrome(string s) {
//统计各字符出行的次数
std::unordered_map<char, int> mFreq;
for (const auto&ch : s)
{
mFreq[ch]++;
}
int iRet = 0;
//记录组间移动后各字符的位置
std::unordered_map<char, vector> mLeft, mRight;
int iLeftCnt = 0, iRightCnt = 0;
for (int i = 0; i < s.length(); i++)
{
const char& ch = s[i];
if (mLeft[ch].size() < mFreq[ch] / 2)
{
iRet += i - iLeftCnt;//组间移动
mLeft[ch].emplace_back(iLeftCnt);
iLeftCnt++;
}
else
{
mRight[ch].emplace_back(iRightCnt);
iRightCnt++;
}
}
//如果是奇数,左边末尾加上
for (auto& it : mLeft)
{
if (mFreq[it.first] & 1)
{
it.second.emplace_back(iLeftCnt++);
}
}
//vMove[i]的值是b,表示目前在i位置的字符要移动到b位置
vector vMove(iRightCnt);
for (auto it : mRight)
{
const auto& vLeft = mLeft[it.first];
for (int i = 0; i < it.second.size(); i++)
{
const int j = vLeft.size() - 1 - i;
const int iNewPos = iRightCnt -1 - vLeft[j];
vMove[it.second[i]] = iNewPos;
}
}

	//逆序对数就是组间移动数
	CTreeArr<int> tree(iRightCnt);
	for (int i = iRightCnt - 1; i >= 0; i--)
	{
		iRet += tree.Sum(vMove[i]);
		tree.Add(vMove[i], 1);
	}
	return iRet;
}

};

2023年7月版

class Solution {
public:
int minMovesToMakePalindrome(string s) {
m_c = s.length();
int iRet = 0;
for (int left = 0; left < m_c / 2; left++)
{
int right = s.length() - 1;
for (; s[right] != s[left]; right–);
if (left == right)
{
iRet += m_c / 2 - left;
}
else
{
iRet += s.length() - 1 - right;
s.erase(right, 1);
}
}
return iRet;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业
。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/442788.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql-DBA(2)-日志-数据库复制

1.mysqlbinlog 查看日志-精确查找-增量备份 1.1查看日志 mysqlbinlog binlog.000003 -vv --base64auto | less //两种都有 base64加密和看的懂的明文 mysqlbinlog binlog.000003 -vv --base64never | less //不显示 mysqlbinlog binlog.000003 -vv --base64decode-rows …

Flask python开发篇: 写一个简单的接口

第一步&#xff1a;新建flask项目 参考使用pycharm新建一个项目 打开pycharm&#xff0c;根据下面图中箭头顺序&#xff0c;新建一个flask的项目&#xff1b; 第二步&#xff1a;运行项目&#xff0c; 安装成功以后&#xff0c;会有个app.py文件&#xff0c;打开以后&#…

STM32CubeIDE基础学习-STM32CubeIDE软件程序下载方法

STM32CubeIDE基础学习-STM32CubeIDE软件代码下载方法 文章目录 STM32CubeIDE基础学习-STM32CubeIDE软件代码下载方法前言第1章 代码下载第2章 下载器固件更新总结 前言 编写完代码&#xff0c;一般都会选择在线下载程序的方式进行验证该程序是否正确&#xff0c;如果发现结果和…

回收站选址(CCF 201912-2)解题思路

分析 把x,y坐标拼接成一个字符串&#xff08;x,y&#xff09;作为Set的key&#xff0c;保存到Set中&#xff0c;遍历Set&#xff0c;取出坐标&#xff0c;然后判断上下左右四个点是否在Set中&#xff0c;如果在&#xff0c;进而判断&#xff0c;四个角是否在Set中&#xff0c;…

搜索引擎推广6种策略助你站在市场顶峰的有效方法-华媒舍

如何有效推广自己的产品或服务变得至关重要。6种引擎霸屏推广策略是帮助你站在市场顶峰的有效方法&#xff0c;下面将逐一介绍这些策略。 1.搜索引擎优化&#xff08;SEO&#xff09; 搜索引擎优化是提升网站在搜索引擎结果页&#xff08;SERP&#xff09;中排名的策略。通过…

股票价格预测项目

项目介绍 背景 股票价格预测一直是金融领域的热点问题。准确的预测可以帮助投资者作出更明智的决策。本项目旨在使用机器学习技术&#xff0c;特别是长短期记忆网络&#xff08;LSTM&#xff09;&#xff0c;来预测股票价格。 目标 开发一个基于LSTM的股票价格预测模型。使…

Mamba-minimal Mamba的最小限度实现 (二)

文章目录 链接导入所需包class ModelArgsclass Mambadef __ init __def forward class ResidualBlockclass RNSNorm文本生成demo manba的简单最小限度实现&#xff0c;和原始论文实现 state-spaces/mamba (github.com)相比&#xff0c;为了可读性对参数没有很好的初始化&#…

c++ 常用的STL

前言 写这篇博客目的是为了记录在刷算法题中使用过的STL&#xff0c;因为有些不太常用的会遗忘。这篇博客只是作为笔记&#xff0c;不是详细的STL&#xff0c;因此只会对常用方法说明&#xff0c;不会详细介绍。此外在后面用到新的STL内容时会再补充。 列队 基础列队 基本列…

Prompt进阶系列1:LangGPT(从编程语言反思LLM的结构化可复用提示设计框架)

Prompt进阶系列1:LangGPT(从编程语言反思LLM的结构化可复用提示设计框架) 大语言模型 (Large Language Models, LLMs) 在不同领域都表现出了优异的性能。然而&#xff0c;对于非AI专家来说&#xff0c;制定高质量的提示来引导 LLMs 是目前AI应用领域的一项重要挑战。现有的提示…

ARM/Linux嵌入式面经(二):芯片原厂

uart如何进行通信&#xff0c;模块发给uart数据信息后经历了什么 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发传输器&#xff09;是一种用于串行通信的协议&#xff0c;它使用一对传输线&#xff08;TX和RX&#xff09;进行双向通信…

阿里云服务器地域所在城市分布表_北京杭州深圳及全球区域

2024年最新阿里云服务器地域分布表&#xff0c;地域指数据中心所在的地理区域&#xff0c;通常按照数据中心所在的城市划分&#xff0c;例如华北2&#xff08;北京&#xff09;地域表示数据中心所在的城市是北京。阿里云地域分为四部分即中国、亚太其他国家、欧洲与美洲和中东&…

Autodl中tar.gz无法解压问题

在云服务器中&#xff0c;我们常把文件压缩转移至其他实例中&#xff0c;但是我们有时会发现&#xff0c;压缩可以但是解压缩却遇到了问题&#xff0c;下面给出了正确的压缩和解压指令。 1 压缩 tar -cvf archieve.tar.gz aaa(archieve.tar.gz为压缩后的压缩包名称&#xff0c…

【Java.mysql】——增删查改(CRUD)之 增查(CR) 附加数据库基础知识

目录 &#x1f6a9;数据库操作 &#x1f388;创建数据库 &#x1f388;使用数据库 &#x1f388;删除数据库 &#x1f6a9;数据类型 &#x1f6a9;表的操作 &#x1f388;创建表 &#x1f308;查看表结构 &#x1f388;删除表 ❗练习(综合运用) &#x1f5a5;️新增…

【黑马程序员】STL实战--演讲比赛管理系统

文章目录 演讲比赛管理系统需求说明比赛规则程序功能 创建管理类功能描述创建演讲比赛管理类 菜单功能添加菜单成员函数声明菜单成员函数实现菜单功能测试 退出功能添加退出功能声明退出成员函数实现退出功能测试 演讲比赛功能功能分析创建选手类比赛成员属性添加初始化属性创建…

KVM技术原理及安装KVM并且在KVM里面安装RHEL8

目录 一、kvm原理 1..1虚拟化概念 1.2 虚拟化产生背景 1.3虚拟化架构 1.4主流的虚拟化技术 1.5阐述个人对虚拟化技术的几种分类认知 二、安装KVM并且在KVM里面安装RHEL8 2.1在RHEL8主机上安装KVM 2.2安装完成后&#xff0c;使用virt-manager命令打开虚拟机管理图形界面…

Python错题集-8:AttributeError(找不到对应的对象的属性)

1问题描述 AttributeError: AxesSubplot object has no attribute arc 2代码详情 import matplotlib.pyplot as plt# 创建一个新的图形和坐标轴 fig, ax plt.subplots()# 定义弧线的参数 center (0.5, 0.5) # 圆心坐标 (x, y) width 1.0 # 半径 height 0.5 # 半径 ang…

Charles抓包工具使用

Charles简介 Charles是一款基于HTTP协议的代理服务器和HTTP监视器&#xff0c;通过将自己设置为电脑或浏览器的网络访问代理&#xff0c;能够截取请求和请求结果&#xff0c;从而达到分析抓包的目的。它允许开发者查看所有连接互联网的HTTP通信&#xff0c;包括请求、响应和HTT…

【漏洞复现】Linksys E2000 position.js 身份验证绕过漏洞(CVE-2024-27497)

0x01 产品简介 Linksys E2000是一款由思科&#xff08;Cisco&#xff09;品牌推出的无线路由器&#xff0c;它是一款支持2.4GHz和5GHz双频段的无线路由器&#xff0c;用户可以避开拥挤的2.4GHz频段&#xff0c;独自享受5GHz频段的高速无线生活。 0x02 漏洞概述 Linksys E200…

JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比

1、什么是JVM&#xff1f; JVM本质上就是一个软件&#xff0c;是计算机硬件的一层软件抽象&#xff0c;在这之上才能够运行Java程序&#xff0c;JAVA在编译后会生成类似于汇编语言的JVM字节码&#xff0c;与C语言编译后产生的汇编语言不同的是&#xff0c;C编译成的汇编语言会…

hadoop集群部署教程

文章目录 前言一、相关介绍1. 配置文件位置1.1 只读默认配置文件1.2 可修改配置文件1.3 相关环境变量配置文件 二、安装准备1. 准备centos2. 配置集群免密登录3. 部署规划4. 安装条件5. 安装jdk 三、安装hadoop1. 下载并解压hadoop2. 设置环境变量2.1 设置hadoop安装目录环境变…