当前位置: 首页 > news >正文

【树状数组 队列】1505. 最多 K 次交换相邻数位后得到的最小整数

本文涉及知识点

树状数组 队列

LeetCode1505. 最多 K 次交换相邻数位后得到的最小整数

给你一个字符串 num 和一个整数 k 。其中,num 表示一个很大的整数,字符串中的每个字符依次对应整数上的各个 数位 。
你可以交换这个整数相邻数位的数字 最多 k 次。
请你返回你能得到的最小整数,并以字符串形式返回。
示例 1:
输入:num = “4321”, k = 4
输出:“1342”
在这里插入图片描述

解释:4321 通过 4 次交换相邻数位得到最小整数的步骤如上图所示。
示例 2:
输入:num = “100”, k = 1
输出:“010”
解释:输出可以包含前导 0 ,但输入保证不会有前导 0 。
示例 3:
输入:num = “36789”, k = 1000
输出:“36789”
解释:不需要做任何交换。
示例 4:
输入:num = “22”, k = 22
输出:“22”
示例 5:
输入:num = “9438957234785635408”, k = 23
输出:“0345989723478563548”
提示:
1 <= num.length <= 30000
num 只包含 数字 且不含有 前导 0 。
1 <= k <= 109

树状数组

第一种操作让s[i1]变小,第二种操作让s[i1+1…n-1]都变小。显然第一种操作比第二种操作更小。故i从小到大处理s[i]。
处理s[i]时,依次枚举下标最小的s[i]等于ch ,ch = ‘0’ to ‘9’ ,如果能交换则交换,并处理下一个i。
这样做的时间复杂度是:O(nn),超时。
令某字符的原始下标为i1,其它字符交换后若干次后i1的变化规律。如果起始位置都小于i1或都大于i1则对i1无影响。
由于从小到大处理i,所以起始位置i,一定小于i1。只需要统计大于i1的交换次数。如果原始下标大于i1的交换次数为cnt1,则i1当前的左边为i1+cnt1。 i1+cnt1需要交换i1+cnt1- i 次。下标大于i1的交换次数=总交换次数(i) - 下标小于等于i1的交换次数。
如果算上自己交换自己,交换一定能成功。
队列数组 indexs[i]升序记录 i+‘0’
交换成功的队列出队。
时间复杂度: O(nlogn)

代码

核心代码

template<class ELE = int >
class CTreeArr
{
public:CTreeArr(int iSize) :m_vData(iSize + 1){}void Add(int index, ELE value){index++;while (index < m_vData.size()){m_vData[index] += value;index += index & (-index);}}ELE Sum(int index){index++;ELE ret = 0;while (index){ret += m_vData[index];index -= index & (-index);}return ret;}ELE Get(int index){return Sum(index) - Sum(index - 1);}
private:vector<ELE> m_vData;
};class Solution {
public:string minInteger(string num, int k) {queue<int> indexs[10];for (int i = 0; i < num.length(); i++) {indexs[num[i] - '0'].emplace(i);}string ret;CTreeArr<int> ta(num.length());for (int i = 0; i < num.length(); i++) {for (int j = 0; j < 10; j++) {if (indexs[j].empty()) { continue; }const int inx = indexs[j].front();const int cnt1 = i - ta.Sum(inx);const int need = inx + cnt1 - i;if (need <= k) {k -= need;ta.Add(inx, 1);ret += ('0' + j);indexs[j].pop();break;}}}return ret;}
};

单元测试

template<class T1,class T2>
void AssertEx(const T1& t1, const T2& t2)
{Assert::AreEqual(t1 , t2);
}template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{Assert::AreEqual(v1.size(), v2.size());	for (int i = 0; i < v1.size(); i++){Assert::AreEqual(v1[i], v2[i]);}
}template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{sort(vv1.begin(), vv1.end());sort(vv2.begin(), vv2.end());Assert::AreEqual(vv1.size(), vv2.size());for (int i = 0; i < vv1.size(); i++){AssertEx(vv1[i], vv2[i]);}
}namespace UnitTest
{string num;int k;TEST_CLASS(UnitTest){public:TEST_METHOD(TestMethod0){num = "4321", k = 4;auto res = Solution().minInteger(num, k);AssertEx(string("1342"), res);}TEST_METHOD(TestMethod2){num = "100", k = 1;auto res = Solution().minInteger(num, k);AssertEx(string("010"), res);}TEST_METHOD(TestMethod3){num = "36789", k = 1000;auto res = Solution().minInteger(num, k);AssertEx(string("36789"), res);}TEST_METHOD(TestMethod4){num = "22", k = 22;auto res = Solution().minInteger(num, k);AssertEx(string("22"), res);}TEST_METHOD(TestMethod5){num = "294984148179", k = 11;auto res = Solution().minInteger(num, k);AssertEx(string("124498948179"), res);}};
}

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

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

相关推荐

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

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

http://www.lryc.cn/news/382929.html

相关文章:

  • 【附精彩文章合辑】当谈到程序的“通用性”与“过度设计”的困境时,我们可以通过一些具体的例子来更直观地阐述这些解决方案
  • Word中删除空白页
  • 30.Netty进阶-黏包半包解决方案-短链接
  • 斜堆(数据结构篇)
  • 河南大学24计算机考研数据,有三个学院招收计算机相关专业,都是考的408!
  • ubuntu离线安装docker导入镜像
  • 鸿蒙原生应用元服务开发-位置服务申请权限
  • 基于SpringBoot的“智慧食堂”管理系统设计与实现
  • 高效记录收支明细:揭秘如何通过曲线图精准分析每月开销
  • 开发注意事项
  • Vue79-路由组件独有的2个新的生命周期钩子
  • Lua博客网站支持搜索、评论、登录注册
  • BGP高级特性
  • 鸿蒙开发:1.环境搭建和入门
  • python学习 - 设计模式 - 组合模式
  • JavaScript倒序遍历数组:计算年度累积值
  • 华为仓颉编程语言观感
  • Elasticsearch:倒数排序融合 - Reciprocal rank fusion - 8.14
  • Day13—大语言模型
  • php基础语法_面向对象
  • 开源模型应用落地-LangChain高阶-LCEL-表达式语言(八)
  • c# 协议数据计算陀螺仪的角度,带符号
  • ArcGIS arcpy代码工具——批量要素裁剪栅格影像
  • discuz插件之优雅草超级列表互动增强v1.2版本更新
  • 三、用户中心项目笔记----后端多环境实战+原始部署
  • SpringMVC的使用
  • Vue73-命名路由
  • TrustOne发布一周年成绩单,15000家数智化转型客户的选择!
  • Nginx实战:故障处理_后端服务正常,nginx偶发502(Bad Gateway)
  • mac系统清理软件哪个好用?CleanMyMac X清理工具轻松拿捏mac