一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
前言
每日一题,轻松解题
每日一题为刷题系列 每日刷一题LeetCode题,并且对题目进行分析,分享思路。
正文
:邻位交换的最小次数
难度:中等
题目要求:
给你一个表示大整数的字符串 num ,和一个整数 k 。
如果某个整数是 num 中各位数字的一个 排列 且它的 值大于 num ,则称这个整数为 妙数 。可能存在很多妙数,但是只需要关注 值最小 的那些。
例如,num = "5489355142" : 第 1 个最小妙数是 "5489355214" 第 2 个最小妙数是 "5489355241" 第 3 个最小妙数是 "5489355412" 第 4 个最小妙数是 "5489355421" 返回要得到第 k 个 最小妙数 需要对 num 执行的 相邻位数字交换的最小次数 。
测试用例是按存在第 k 个最小妙数而生成的。
举个例子
输入:num = "5489355142", k = 4
输出:2
解释:第 4 个最小妙数是 "5489355421" ,要想得到这个数字:
- 交换下标 7 和下标 8 对应的位:"5489355142" -> "5489355412"
- 交换下标 8 和下标 9 对应的位:"5489355412" -> "5489355421"
:解题
方法一 :模拟 + 贪心
模拟 + 贪心
贪心
贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法
算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果
以上面的问题问题,若使用贪心算法求出的结果,有时候不一定是最优的结果,因为有可能成本问题不是最好的,但是它是相对接近最优解的
解题思路:
本题是一道由两个经典模型进行拼接得到的题目。
-
第一步我们需要求出比num 大的第 kk 个排列 num k
-
第二步我们需要将 num 通过交换操作得到num k,每一步交换操作只能交换相邻的两个字符。
编辑代码:
class Solution {
public:
int getMinSwaps(string num, int k) {
string num_k = num;
for (int i = 0; i < k; ++i) {
next_permutation(num_k.begin(), num_k.end());
}
int n = num.size();
int ans = 0;
for (int i = 0; i < n; ++i) {
if (num[i] != num_k[i]) {
for (int j = i + 1; j < n; ++j) {
if (num[j] == num_k[i]) {
for (int k = j - 1; k >= i; --k) {
++ans;
swap(num[k], num[k + 1]);
}
break;
}
}
}
}
return ans;
}
};
总结
无论做什么分析最重要,其中我们分析了题目,分析了解题思路,其实在分析完解题思路后,代码其实就是很简单的事情了,养成习惯,无论做什么之前,都要进行分析,这样有助于你更快更好的完成这件事。