LeetCode 670.最大交换 图解(附Java代码)

427ef4152dbf4b6c92618a198935cb6c.png

  📝个人主页:哈__

期待您的关注 

1b7335aca73b41609b7f05d1d366f476.gif

今天给大家分享一道LeetCode的贪心类算法题目。

一、题目描述

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

示例 1 :

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

示例 2 :

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

注意:

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

二、方法及思路

看题目中的描述,给出的一个数字只让我们交换一次,然后让这个数字的值达到最大?一开始想区确实没有思路,但抛开代码层面, 如同示例1给出的2736,你又能很轻松的得知交换后的数字为7236,不是7632,也不是7263。这是因为题目给出了我们限制,只让我们交换仅仅一次。

既然选择贪心,那么我就可能想要挑出这个数组中最大的值交换到这个数前边的一个位置。2736就是7最大,然后和2交换。9973就是9最大(可以把这个最大的值的下标索引当作是第二个9,因为我们是倒着来遍历数组的),但是这个9前边又没有可以交换的值,所以9973不交换。

如果这样的话问题就来了,如果题目给出的是9937呢?你是否还想要挑出一个最大的数交换?如果是这样的话你挑出最大的值为9,但9无法和前边的数进行交换了,这样就会导致结果出错。

所以仅仅记录数组中最大值的坐标是不行的。

在这里我进行了三个变量的初始化,一个是maxIndex(最大值的下标索引),index1,index2(需要交换的值的两个索引)

bd8cdeb7b132440f9b73182ba369762f.png

我们先将maxIndex初始化为最后一个索引,在我们从后往前找的时候不仅要记录这个maxIndex的变化,同时还要记录一下index1和index2,这两个变量就是用来记录我们最后要交换哪两个值的,初始化都为-1。那么到底什么情况需要交换呢?当我们开始逆序遍历,maxIndex指向的值大于当前遍历的值时,我们就应该将这两个值交换。我们希望的是最后的maxIndex的值能越靠前放越好,所以我们使用index1和index2记录下这两个需要交换的坐标而不实际交换。

下面是遍历的记录。

当j遍历到3的时候,maxIndex指向的6>3更新index1和index2索引。

76a2683455124b98999cc9a2d4b86058.png

当j遍历到7的时候,7>maxIndex指向的6,更新maxIndex索引

6fe8622589f040378404bd0129f9938f.png 

当j遍历到2的时候, maxINdex指向的7>2,更新index1和index2

2f03e09621a046cc9349765ca59c1be0.png 

至此,遍历结束,最后交换index1和index2指向的值。 

那么9937这样的值是否就可以正确的遍历了呢?

三、代码

class Solution {
    public int maximumSwap(int num) {
       String str = String.valueOf(num);
       char [] arr = str.toCharArray();
       int maxIndex = arr.length-1;
       int index1 = -1;
       int index2 = -1;
      for(int i = arr.length-1;i>=0;i--){
          if(arr[i]>arr[maxIndex]){
              maxIndex = i;
          }else if(arr[i]<arr[maxIndex]){
              index2 = i;
              index1 = maxIndex;
          } 
      }
      if(index1==-1) return num;
      char tmpVal = arr[index1];
      arr[index1] = arr[index2];
      arr[index2] = tmpVal;
      return Integer.parseInt(String.valueOf(arr));
    }
}

949f931d0bb045eead75cd669fb6f531.png

 

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值