LintCode 1095.最大的交换 渣渣学算法系列

本文通过动态规划解决了一道数字排列问题,关键在于找到并利用数字中的最大值进行有效的交换,以达到最大的可能数值。文章详细描述了将数字转化为数组、排序、判断和交换的过程,最终实现了算法的有效性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法虐我千百遍,我却视她为初恋…
作为渣渣的我真的很无奈
这其实不是一道难题,至少想通之后发现…
昨天晚上看了很多动态规划的教程,然后跟着再lintcode上做了几道题,准备睡觉时突然有个弹窗引起了我的注意,好奇的点开一看,是一道题目,描述的很简洁,而且数据规模也很明确,所以就抱着试一试的态度去做了一下,结果卡在了33%的用例处了,因为没有考虑9804这种情况,因为我一开始只靠考虑了最大值换到0位置的情况…然后就悲痛的代码,然而确实无济于事,我开始想用一种新的思路,点开了discuss,居然有人说有些代码有问题,而我作为渣渣当然不敢bb,因为我又不是vip也看不到他们的代码呀…懵逼的点开笔记之类的东西,注意到一个词语,最大值,是的,这个最大值就是破题的关键.
于是想法诞生如下:

  • 先把num转化为十进制数组 如 9804 转化为 {9,8,0,4}
  • 用两个数组来接受这个转换后的结果
  • 将第二个数组排序,这里先用Arrays.sort()进行从小到大的排序,然后再倒过来,这里我用的两两交换,其实也可以用别的
  • 然后判断(也就是本题的切题思想)
  • 本题提示只能交换一次
  • 如果最大值不在首位,即data[0] != sort[0],那么找到最大值再data中的位置,然后把它和首位即data[0]交换,跳出循环
  • 如果最大值在首位,那么考虑第二大的值在不在第二位,也就是data[1] == sort[1]??如果data[1] != sort[1],向后寻找第二大的值的位置,把第二大的值和data[1]交换,跳出循环
  • 值得注意的是,如果有相同的最大值,一定要找到最后面那个最大值,例如 98989 ,排序得99988,发现8和9不相等,这时从8后面开始找9,如果找到第一个9就交换,那么得到的是99889,但如果找到最后的那个9和前面的8交换,那么就是99988,显然99988>99889>98989,所以在循环中不要找到最大值就break,直接break是绝对不行的.
  • 如果…以此类推
  • 例如: 9804 转化为 {9,8,0,4} ,data = {9,8,0,4} ,sort = {9,8,0,4} ,排序后的sort 为 {9,8,4,0}
  • 9 = 9 , 8 = 8 ,0 != 4 ,向后寻找找到4,然后和0进行交换,跳出循环
  • 最后把data数据的数再转换成十进制数返回就可以了…

想法比较简单,编码水平很次,希望大家不要嫌弃.以下为ac的code,java实现

public class Solution {
    /**
     * @param num: a non-negative intege
     * @return: the maximum valued number
     */
    public static int maximumSwap(int num) {
        if( num < 10 )
            return num;
        //计算num 有多少位
        int t1 = num;
        int len = 0;
        while(t1>0){
            t1 /= 10;
            len++;
        }
        int[] data = new int[len];
        int[] sort = new int[len];
        //把每一位存到数组里
        t1 = num;
        int t2 = len;
        while(t2>0){
            data[t2-1] = t1%10;
            sort[t2-1] = t1%10;
            t1/=10;
            t2--;
        }
        Arrays.sort(sort);
        int t;
        for(int i=0 , j=sort.length-1; i < j ; i++,j--){
            t = sort[i];
            sort[i] = sort[j];
            sort[j] = t;
        }
        // for(int c:data)
        //     System.out.print(c);
        // System.out.println();
        // for(int c:sort)
        //     System.out.print(c);
        // System.out.println();
        boolean flag = true;
        for(int i=0 ; i<data.length ; i++){
            if(data[i] != sort[i]){
                //找到那个最大值
                int mark = i+1;
                for(int j = i+1 ; j < data.length ; j++){
                    if(data[j] == sort[i]){
                        mark = j;
                    }
                }
                int temp = data[i];
                data[i] = data[mark];
                data[mark] = temp;
                //交换
                break;
            }
        }
        int res = 0;
        for(int i = 0 ; i < data.length ; i++){
            res = res *10 + data[i];
        }
        if(false)
            return num;
        else
            return res;
    }
}

截止到2019/2/24 1:09,
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值