首页 > 其他分享 >LeetCode-670. 最大交换-题解分析

LeetCode-670. 最大交换-题解分析

时间:2023-01-24 21:12:36浏览次数:70  
标签:候选 candidate int 题解 670 maxIdx str 交换 LeetCode

题目来源

670. 最大交换

题目详情

给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。

示例 1 :

输入: 2736
输出: 7236
解释: 交换数字2和数字7。

示例 2 :

输入: 9973
输出: 9973
解释: 不需要交换。

注意:

  1. 给定数字的范围是 [0, 108]

题解分析

本题一开始看没有明确的解题思路,会感觉无从下手。其实,本题的关键是越往后找到一个最大的数与越靠前的最小的数进行交换。

核心思路是将最靠后的最大的数,与最靠前的小于它的数交换(若存在),得到最大结果。具体的解法是使用贪心法求解最优数字交换方案。

本题使用贪心法需要考虑的两个核心思路是:

  • 选择哪个数作为候选数与前面的数交换?——将最靠后的数定为候选数,若它之前出现了更大的数,则更新候选数为该数。
  • 选择哪个数与候选数交换?——只有当候选数之前存在更小的数时,才需要交换这两数。若更靠前的位置出现小于候选数的数,则将它与候选数交换。

本题可以同时设置一个最大索引maxIdx以及一个候选索引candidate分别来记录右边最大值以及左边的候选值。字符串的遍历方向从右往左,不断比较记录最大值的位置,当遇到小于最大值的位置时,将其置为候选位置。

需要注意的是,这里在记录candidate候选位置的时候,同时需要记录一个endIdx指针,该指针记录了最大值索引。之所以不直接使用maxIdx表示最终需要交换的最大值索引,是因为前面可能出现比后面最大值还大的数字,这些数字不应该被替换,只需要替换最小值之后的候选位置。

java实现

class Solution {
    public int maximumSwap(int num) {
        String str = String.valueOf(num);
        int len = str.length();
        int maxIdx = len - 1;
        int candidate = -1;
        int endIdx = -1;
        for (int i = len-1; i >= 0; i--) {
            int number = str.charAt(i) - '0';
            int maxs = str.charAt(maxIdx) - '0';
            if (number > maxs) {
                maxIdx = i;
            } else if (number < maxs) {
                candidate = i;
                endIdx = maxIdx;
            }
        }
        if (candidate < 0) {
            return num;
        }
        String res = swap(str, candidate, endIdx);
        return Integer.parseInt(res);
    }

    private String swap(String str, int i, int j) {
        StringBuilder sb = new StringBuilder(str);
        sb.setCharAt(i, str.charAt(j));
        sb.setCharAt(j, str.charAt(i));
        return sb.toString();
    }
}

标签:候选,candidate,int,题解,670,maxIdx,str,交换,LeetCode
From: https://www.cnblogs.com/GarrettWale/p/17066388.html

相关文章

  • 题解 ARC154D【A + B > C ?】
    显然\(1+1>x\)对任意大于\(1\)的正整数\(x\)都不成立。利用这一点,我们可以在\(n-1\)次询问内问出\(1\)的位置。具体地,首先假设\(p_1\)为\(1\),记我们假设的为......
  • 莫比乌斯函数(P3455 题解)
    题目链接。我们定义\(n\)的莫比乌斯函数为\(\mu_n\)。我们将\(n\)分解质因式后为\(n=p_1^{\alpha_1}p_2^{\alpha_2}\cdotsp_k^{\alpha_k}\)则\(\mu_n=\begin......
  • CF1726D 题解
    EdgeSplit。一开始nt了,以为红边为一颗树,蓝边为剩余边,蓝边就不会有环了。假设有\(n\)个点,\(m\)条边,且这些边没有出现环,那么连通块的数量为\(n-m\),因为不存在环,......
  • AT_abc285_e 题解
    WorkorRest。我们考虑相邻两个假期之间的工作效率和。设\(len\)为相邻两个假期间隔的天数。举个例子,如果假期为\(\{1,3,7\}\),那么\(len\)为\(\{1,4\}\)。根......
  • CF1768C 题解
    \(\mathcalSolution\)【题意】题目要你构造两个序列\(p,q\),满足\(\max\{p_i,q_i\}=a_i\)。【分析】如果满足\(\max\{p_i,q_i\}=a_i\),则满足\(p_i=a_i,q_i\le......
  • CF1768D 题解
    \(\mathcalSolution\)【题意】我们可以交换任意两个数,求最小操作几次能让逆序对变成\(1\)。【分析】如果逆序对为\(1\)的排列一定是:\(2,1,\cdotsn\)\(1,3,......
  • ABC281E 题解
    \(\mathcalSolution\)本题的思路类似于对顶堆。用两个multiset来维护。\(S_1\)为第一个multiset;\(S_2\)为第二个multiset。\(S_1\)维护前\(K\)个值,\(S_2\)......
  • AT_abc277_e 题解
    \(\mathcalSolution\)【题意】给定无向图,当\(a_i=1\)时,该条边才能走。在给我们\(k\)个点,\(S_1,S_2,\cdots,S_k\),到了这些点可以选择是否取反\((1\to0,0\t......
  • 2023牛客寒假算法基础集训营1 个人题解(ACDHKL)
    A.WorldFinal?WorldCup!(I)题意:给10场比赛的点球输赢情况,奇数为A队点球,偶数为B队点球思路:用两个变量x,y来分别存A队当前赢的场次和B队当前赢的场次然后就就扫......
  • CodeForces-907#B 题解
    正文设数组\(c_{x,y,i,j}\)代表\((x,y)\)位置的大格子中\((i,j)\)位置的小格子。很显然,输入中字符的输入顺序是要调整的,实际的顺序是\(x,i,y,j\)。对于输入的\(......