力扣每日一题240122

670.最大交换

思路:解题的过程就是找到需要交换的两个数的过程。

先由任意一个例子开始思考,如2431.显而易见,最符合题意的交换方式是把4换到最高位,最高位的2换到4原来所在的那一位。

再发散思维思考,这种交换方式是否符合所有可能的例子。如果给定的数据是4231,显然4作为最高位是不能被换下去的,如果4被换下去只会让这个数变小不会变大。那么需要被换下去的数就是左数第二位。需要从低位换到高位的数则是除了4之外,这串数字中最大的一个数,也就是3.

以此类推,如果给定的数据是4312,前两位都不需要动,交换第三位和第三大的数。如果给定4321,数字串已经是从大到小排列,不需要交换。

分析到这里,我们可以抽象出交换数字时所依靠的“模板”:原数字串从大到小排列过后的数字串(即元素不变,排列顺序变化)。这是一个重要的概念。

我们把读取的数字转化为字符串:

string s = to_string(num);

把读取的字符串拷贝一份,对副本进行从大到小排序得到模板串。

 sort(t.rbegin(),t.rend());

现在我们要想个办法,让cpu来判断要换哪一位。cpu不能像人眼一样“显而易见”得出结论,我们试着让它按位遍历。从分析方法中我们可以抽象出,让程序把给定串和模板串从高位到低位依次比较,如果相同,则说明第i位(当前位)不用换,继续看下一位;如果不相同,则说明给定串的第i位需要由高位换到低位,换上来的那个数字是模板串中的第i位。我们再去给定串中找到与模板串中第i位相同的数字,在给定串中进行交换。

最后把交换好的给定串再转化成字符串,就大功告成了。

参考了力扣@文刀漂洋的题解:

class Solution {
public:
    int maximumSwap(int num) {
        string s = to_string(num), t = s;
        sort(t.rbegin(),t.rend());//从大到小排列。内存分配?

        for (int i = 0; i < s.size(); i ++) {
            if (s[i] != t[i]) //s是原字符串数组,t是排列好的模板
            {
                swap(s[i], *find(s.rbegin(), s.rend(), t[i])); 
                //在s中查找与t[i]相等的元素,并将s[i]与找到的元素交换
                break;
            }
        }
        return stoi(s); //将字符串转成int整数
    }
};
//这代码用了好多stl

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值